From 9aad8d683dc6feca0487ccbf74d129906f262739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 14 Oct 2021 16:25:07 +0200 Subject: [PATCH 0001/1748] common.sh: printStackTrace() and assertFail() --- scripts/common.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/scripts/common.sh b/scripts/common.sh index b3a5f82e48..1ace4d5deb 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -33,12 +33,45 @@ else function printLog() { echo "$(tput setaf 3)$1$(tput sgr0)"; } fi +function printStackTrace +{ + printWarning "" + printWarning "Stack trace:" + + local frame=1 + while caller "$frame" > /dev/null + do + local lineNumber file function + + # `caller` returns something that could already be printed as a stacktrace but we can make + # it more readable by rearranging the components. + # NOTE: This assumes that paths do not contain spaces. + lineNumber=$(caller "$frame" | cut --delimiter " " --field 1) + function=$(caller "$frame" | cut --delimiter " " --field 2) + file=$(caller "$frame" | cut --delimiter " " --field 3) + >&2 printf " %s:%d in function %s()\n" "$file" "$lineNumber" "$function" + + ((frame++)) + done +} + function fail() { printError "$@" return 1 } +function assertFail() +{ + printError "" + (( $# == 0 )) && printError "Assertion failed." + (( $# == 1 )) && printError "Assertion failed: $1" + printStackTrace + + # Intentionally using exit here because assertion failures are not supposed to be handled. + exit 2 +} + function msg_on_error() { local error_message From b85172b0557c3bb6624d39479d7a6cffac4f141f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 14 Oct 2021 18:43:04 +0200 Subject: [PATCH 0002/1748] common.sh: Print the source code from locations indicated in the stack trace --- scripts/common.sh | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/scripts/common.sh b/scripts/common.sh index 1ace4d5deb..6d70a0840c 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -19,6 +19,10 @@ # (c) 2016-2019 solidity contributors. # ------------------------------------------------------------------------------ +# Save the initial working directory so that printStackTrace() can access it even if the sourcing +# changes directory. The paths returned by `caller` are relative to it. +_initial_work_dir=$(pwd) + if [ "$CIRCLECI" ] then export TERM="${TERM:-xterm}" @@ -41,7 +45,7 @@ function printStackTrace local frame=1 while caller "$frame" > /dev/null do - local lineNumber file function + local lineNumber line file function # `caller` returns something that could already be printed as a stacktrace but we can make # it more readable by rearranging the components. @@ -49,7 +53,23 @@ function printStackTrace lineNumber=$(caller "$frame" | cut --delimiter " " --field 1) function=$(caller "$frame" | cut --delimiter " " --field 2) file=$(caller "$frame" | cut --delimiter " " --field 3) + + # Paths in the output from `caller` can be relative or absolute (depends on how the path + # with which the script was invoked) and if they're relative, they're not necessarily + # relative to the current working dir. This is a heuristic that will work if they're absolute, + # relative to current dir, or relative to the dir that was current when the script started. + # If neither works, it gives up. + line=$( + { + tail "--lines=+${lineNumber}" "$file" || + tail "--lines=+${lineNumber}" "${_initial_work_dir}/${file}" + } 2> /dev/null | + head --lines=1 | + sed -e 's/^[[:space:]]*//' + ) || line="" + >&2 printf " %s:%d in function %s()\n" "$file" "$lineNumber" "$function" + >&2 printf " %s\n" "$line" ((frame++)) done From 3b1b9a0bfb166e94d5690ee72c5f79f7d4d23dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 14 Oct 2021 16:50:14 +0200 Subject: [PATCH 0003/1748] common.sh: Adjust formatting in msg_on_error() and add stack trace --- scripts/common.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/scripts/common.sh b/scripts/common.sh index 6d70a0840c..da5b2d2ef0 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -138,24 +138,30 @@ function msg_on_error() rm "$stdout_file" "$stderr_file" return 0 else - printError "Command failed: $SOLC ${command[*]}" + printError "" + printError "Command failed: ${error_message}" + printError " command: $SOLC ${command[*]}" if [[ -s "$stdout_file" ]] then - printError "stdout:" + printError "--- stdout ---" + printError "-----------" >&2 cat "$stdout_file" + printError "--------------" else - printError "stdout: " + printError " stdout: " fi if [[ -s "$stderr_file" ]] then - printError "stderr:" + printError "--- stderr ---" >&2 cat "$stderr_file" + printError "--------------" else - printError "stderr: " + printError " stderr: " fi - printError "$error_message" rm "$stdout_file" "$stderr_file" + + printStackTrace return 1 fi } From 0280c8d00ec4756605dc83a8c8c0d9455f24f8cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 14 Oct 2021 18:39:59 +0200 Subject: [PATCH 0004/1748] Use fail and assertFail where appropriate in command-line tests --- scripts/common.sh | 7 ++++++- test/cmdlineTests.sh | 37 ++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/scripts/common.sh b/scripts/common.sh index da5b2d2ef0..6d9b0a3ba8 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -19,6 +19,9 @@ # (c) 2016-2019 solidity contributors. # ------------------------------------------------------------------------------ +# The fail() function defined below requires set -e to be enabled. +set -e + # Save the initial working directory so that printStackTrace() can access it even if the sourcing # changes directory. The paths returned by `caller` are relative to it. _initial_work_dir=$(pwd) @@ -78,6 +81,8 @@ function printStackTrace function fail() { printError "$@" + + # Using return rather than exit lets the invoking code handle the failure by suppressing the exit code. return 1 } @@ -120,7 +125,7 @@ function msg_on_error() shift ;; *) - fail "Invalid option for msg_on_error: $1" + assertFail "Invalid option for msg_on_error: $1" ;; esac done diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 1304da8af8..59c29ca453 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -92,7 +92,7 @@ echo "Using solc binary at ${SOLC}" INTERACTIVE=true if ! tty -s || [ "$CI" ] then - INTERACTIVE="" + INTERACTIVE=false fi # extend stack size in case we run via ASAN @@ -123,7 +123,7 @@ function update_expectation { function ask_expectation_update { - if [[ $INTERACTIVE != "" ]] + if [[ $INTERACTIVE == true ]] then local newExpectation="${1}" local expectationFile="${2}" @@ -142,12 +142,13 @@ function ask_expectation_update e*) "$editor" "$expectationFile"; break;; u*) update_expectation "$newExpectation" "$expectationFile"; break;; s*) return;; - q*) exit 1;; + q*) fail;; esac done fi else - exit 1 + [[ $INTERACTIVE == false ]] || assertFail + fail fi } @@ -252,7 +253,7 @@ EOF printError "Incorrect exit code. Expected $exit_code_expected but got $exitCode." [[ $exit_code_expectation_file != "" ]] && ask_expectation_update "$exitCode" "$exit_code_expectation_file" - [[ $exit_code_expectation_file == "" ]] && exit 1 + [[ $exit_code_expectation_file == "" ]] && fail fi if [[ "$(cat "$stdout_path")" != "${stdout_expected}" ]] @@ -266,7 +267,7 @@ EOF printError "When running $solc_command" [[ $stdout_expectation_file != "" ]] && ask_expectation_update "$(cat "$stdout_path")" "$stdout_expectation_file" - [[ $stdout_expectation_file == "" ]] && exit 1 + [[ $stdout_expectation_file == "" ]] && fail fi if [[ "$(cat "$stderr_path")" != "${stderr_expected}" ]] @@ -280,7 +281,7 @@ EOF printError "When running $solc_command" [[ $stderr_expectation_file != "" ]] && ask_expectation_update "$(cat "$stderr_path")" "$stderr_expectation_file" - [[ $stderr_expectation_file == "" ]] && exit 1 + [[ $stderr_expectation_file == "" ]] && fail fi rm "$stdout_path" "$stderr_path" @@ -300,10 +301,10 @@ function test_solc_assembly_output() if [ -z "$empty" ] then printError "Incorrect assembly output. Expected: " - echo -e "${expected}" + >&2 echo -e "${expected}" printError "with arguments ${solc_args[*]}, but got:" - echo "${output}" - exit 1 + >&2 echo "${output}" + fail fi } @@ -373,7 +374,7 @@ printTask "Running general commandline tests..." then printError "Ambiguous input. Found input files in multiple formats:" echo -e "${inputFiles}" - exit 1 + fail fi # Use printf to get rid of the trailing newline @@ -475,7 +476,8 @@ echo "Done." printTask "Testing library checksum..." echo '' | msg_on_error --no-stdout "$SOLC" - --link --libraries a=0x90f20564390eAe531E810af625A22f51385Cd222 -echo '' | "$SOLC" - --link --libraries a=0x80f20564390eAe531E810af625A22f51385Cd222 &>/dev/null && exit 1 +echo '' | "$SOLC" - --link --libraries a=0x80f20564390eAe531E810af625A22f51385Cd222 &>/dev/null && \ + fail "solc --link did not reject a library address with an invalid checksum." printTask "Testing long library names..." echo '' | msg_on_error --no-stdout "$SOLC" - --link --libraries aveeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeerylonglibraryname=0x90f20564390eAe531E810af625A22f51385Cd222 @@ -503,7 +505,8 @@ SOLTMPDIR=$(mktemp -d) # First time it works echo 'contract C {}' | msg_on_error --no-stderr "$SOLC" - --bin -o "$SOLTMPDIR/non-existing-stuff-to-create" # Second time it fails - echo 'contract C {}' | "$SOLC" - --bin -o "$SOLTMPDIR/non-existing-stuff-to-create" 2>/dev/null && exit 1 + echo 'contract C {}' | "$SOLC" - --bin -o "$SOLTMPDIR/non-existing-stuff-to-create" 2>/dev/null && \ + fail "solc did not refuse to overwrite $SOLTMPDIR/non-existing-stuff-to-create." # Unless we force echo 'contract C {}' | msg_on_error --no-stderr "$SOLC" - --overwrite --bin -o "$SOLTMPDIR/non-existing-stuff-to-create" ) @@ -517,8 +520,8 @@ printTask "Testing assemble, yul, strict-assembly and optimize..." # Test options above in conjunction with --optimize. # Using both, --assemble and --optimize should fail. - echo '{}' | "$SOLC" - --assemble --optimize &>/dev/null && exit 1 - echo '{}' | "$SOLC" - --yul --optimize &>/dev/null && exit 1 + 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 # Non-empty code results in non-empty binary representation with optimizations turned off, @@ -563,8 +566,8 @@ SOLTMPDIR=$(mktemp -d) cd "$SOLTMPDIR" if ! "$REPO_ROOT/scripts/ASTImportTest.sh" then - rm -rf "$SOLTMPDIR" - exit 1 + rm -r "$SOLTMPDIR" + fail fi ) rm -r "$SOLTMPDIR" From d8464101724016dc4f16bababf2994ab7df22c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 14 Oct 2021 20:57:15 +0200 Subject: [PATCH 0005/1748] yul.rst: Clarify that linkersymbol() accepts but does not require a fully qualified library name --- docs/yul.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/yul.rst b/docs/yul.rst index 0a90a28250..9aad572c82 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -959,10 +959,13 @@ to ``loadimmutable("name")`` in the runtime code. linkersymbol ^^^^^^^^^^^^ - -The function ``linkersymbol("fq_library_name")`` is a placeholder for an address literal to be -substituted by the linker. Its first and only argument must be a string literal and represents the -fully qualified library name used with the ``--libraries`` option. +The function ``linkersymbol("library_id")`` is a placeholder for an address literal to be substituted +by the linker. +Its first and only argument must be a string literal and uniquely represents the address to be inserted. +Identifiers can be arbitrary but when the compiler produces Yul code from Solidity sources, +it uses a library name qualified with the name of the source unit that defines that library. +To link the code with a particular library address, the same identifier must be provided to the +``--libraries`` option on the command line. For example this code From 9f48b7419ccc31dd1239933d916eb3b23e55481d Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 14 Oct 2021 16:18:20 +0200 Subject: [PATCH 0006/1748] Do not use named function labels if function names are not unique. --- Changelog.md | 1 + libyul/backends/evm/AsmCodeGen.cpp | 4 +- libyul/backends/evm/EVMCodeTransform.cpp | 16 +- libyul/backends/evm/EVMCodeTransform.h | 11 +- libyul/backends/evm/EVMObjectCompiler.cpp | 2 +- .../inline_assembly_function_name_clash/args | 1 + .../inline_assembly_function_name_clash/err | 5 + .../input.sol | 18 ++ .../output | 168 ++++++++++++++++++ .../yul_function_name_clashes/args | 1 + .../yul_function_name_clashes/err | 1 + .../yul_function_name_clashes/input.yul | 17 ++ .../yul_function_name_clashes/output | 66 +++++++ .../args | 1 + .../err | 1 + .../input.yul | 17 ++ .../output | 93 ++++++++++ .../inlineAssembly/function_name_clash.sol | 13 ++ 18 files changed, 429 insertions(+), 7 deletions(-) create mode 100644 test/cmdlineTests/inline_assembly_function_name_clash/args create mode 100644 test/cmdlineTests/inline_assembly_function_name_clash/err create mode 100644 test/cmdlineTests/inline_assembly_function_name_clash/input.sol create mode 100644 test/cmdlineTests/inline_assembly_function_name_clash/output create mode 100644 test/cmdlineTests/yul_function_name_clashes/args create mode 100644 test/cmdlineTests/yul_function_name_clashes/err create mode 100644 test/cmdlineTests/yul_function_name_clashes/input.yul create mode 100644 test/cmdlineTests/yul_function_name_clashes/output create mode 100644 test/cmdlineTests/yul_function_name_clashes_different_params/args create mode 100644 test/cmdlineTests/yul_function_name_clashes_different_params/err create mode 100644 test/cmdlineTests/yul_function_name_clashes_different_params/input.yul create mode 100644 test/cmdlineTests/yul_function_name_clashes_different_params/output create mode 100644 test/libsolidity/semanticTests/inlineAssembly/function_name_clash.sol diff --git a/Changelog.md b/Changelog.md index ddfe1648e3..8e1a2d55f5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -19,6 +19,7 @@ Bugfixes: * Commandline Interface: Don't return zero exit code when writing linked files to disk fails. * SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``). * TypeChecker: Fix internal error when using user defined value types in public library functions. + * Yul Assembler: Fix internal error when function names are not unique. * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts. diff --git a/libyul/backends/evm/AsmCodeGen.cpp b/libyul/backends/evm/AsmCodeGen.cpp index 5c7865c017..6ef1429061 100644 --- a/libyul/backends/evm/AsmCodeGen.cpp +++ b/libyul/backends/evm/AsmCodeGen.cpp @@ -52,7 +52,9 @@ void CodeGenerator::assemble( builtinContext, _optimizeStackAllocation, _identifierAccessCodeGen, - _useNamedLabelsForFunctions + _useNamedLabelsForFunctions ? + CodeTransform::UseNamedLabels::YesAndForceUnique : + CodeTransform::UseNamedLabels::Never ); transform(_parsedData); if (!transform.stackErrors().empty()) diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index 38eecc245b..531fd1b92f 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -52,7 +52,7 @@ CodeTransform::CodeTransform( EVMDialect const& _dialect, BuiltinContext& _builtinContext, ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen, - bool _useNamedLabelsForFunctions, + UseNamedLabels _useNamedLabelsForFunctions, shared_ptr _context, vector _delayedReturnVariables, optional _functionExitLabel @@ -405,8 +405,12 @@ void CodeTransform::operator()(FunctionDefinition const& _function) if (!m_allowStackOpt) subTransform.setupReturnVariablesAndFunctionExit(); + subTransform.m_assignedNamedLabels = move(m_assignedNamedLabels); + subTransform(_function.body); + m_assignedNamedLabels = move(subTransform.m_assignedNamedLabels); + m_assembly.setSourceLocation(originLocationOf(_function)); if (!subTransform.m_stackErrors.empty()) { @@ -585,8 +589,16 @@ void CodeTransform::createFunctionEntryID(FunctionDefinition const& _function) if (_function.debugData) astID = _function.debugData->astID; + bool nameAlreadySeen = !m_assignedNamedLabels.insert(_function.name).second; + + if (m_useNamedLabelsForFunctions == UseNamedLabels::YesAndForceUnique) + yulAssert(!nameAlreadySeen); + m_context->functionEntryIDs[&scopeFunction] = - m_useNamedLabelsForFunctions ? + ( + m_useNamedLabelsForFunctions != UseNamedLabels::Never && + !nameAlreadySeen + ) ? m_assembly.namedLabel( _function.name.str(), _function.parameters.size(), diff --git a/libyul/backends/evm/EVMCodeTransform.h b/libyul/backends/evm/EVMCodeTransform.h index 8a605b4722..bad9a357ff 100644 --- a/libyul/backends/evm/EVMCodeTransform.h +++ b/libyul/backends/evm/EVMCodeTransform.h @@ -64,6 +64,10 @@ struct CodeTransformContext class CodeTransform { public: + /// Use named labels for functions 1) Yes and check that the names are unique + /// 2) For none of the functions 3) for the first function of each name. + enum class UseNamedLabels { YesAndForceUnique, Never, ForFirstFunctionOfEachName }; + /// Create the code transformer. /// @param _identifierAccessCodeGen used to generate code for identifiers external to the inline assembly /// As a side-effect of its construction, translates the Yul code and appends it to the @@ -78,7 +82,7 @@ class CodeTransform BuiltinContext& _builtinContext, bool _allowStackOpt = false, ExternalIdentifierAccess::CodeGenerator const& _identifierAccessCodeGen = {}, - bool _useNamedLabelsForFunctions = false + UseNamedLabels _useNamedLabelsForFunctions = UseNamedLabels::Never ): CodeTransform( _assembly, _analysisInfo, @@ -108,7 +112,7 @@ class CodeTransform EVMDialect const& _dialect, BuiltinContext& _builtinContext, ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen, - bool _useNamedLabelsForFunctions, + UseNamedLabels _useNamedLabelsForFunctions, std::shared_ptr _context, std::vector _delayedReturnVariables, std::optional _functionExitLabel @@ -193,7 +197,8 @@ class CodeTransform EVMDialect const& m_dialect; BuiltinContext& m_builtinContext; bool const m_allowStackOpt = true; - bool const m_useNamedLabelsForFunctions = false; + UseNamedLabels const m_useNamedLabelsForFunctions = UseNamedLabels::Never; + std::set m_assignedNamedLabels; ExternalIdentifierAccess::CodeGenerator m_identifierAccessCodeGen; std::shared_ptr m_context; diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index a526bf218c..e41a683872 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -72,7 +72,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) context, _optimize, {}, - true /* _useNamedLabelsForFunctions */ + CodeTransform::UseNamedLabels::ForFirstFunctionOfEachName }; transform(*_object.code); if (!transform.stackErrors().empty()) diff --git a/test/cmdlineTests/inline_assembly_function_name_clash/args b/test/cmdlineTests/inline_assembly_function_name_clash/args new file mode 100644 index 0000000000..4299d023e8 --- /dev/null +++ b/test/cmdlineTests/inline_assembly_function_name_clash/args @@ -0,0 +1 @@ +--experimental-via-ir --combined-json function-debug-runtime --pretty-json --json-indent 4 \ No newline at end of file diff --git a/test/cmdlineTests/inline_assembly_function_name_clash/err b/test/cmdlineTests/inline_assembly_function_name_clash/err new file mode 100644 index 0000000000..5284ffe5ca --- /dev/null +++ b/test/cmdlineTests/inline_assembly_function_name_clash/err @@ -0,0 +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 + +Warning: Source file does not specify required compiler version! +--> inline_assembly_function_name_clash/input.sol diff --git a/test/cmdlineTests/inline_assembly_function_name_clash/input.sol b/test/cmdlineTests/inline_assembly_function_name_clash/input.sol new file mode 100644 index 0000000000..55032c56ed --- /dev/null +++ b/test/cmdlineTests/inline_assembly_function_name_clash/input.sol @@ -0,0 +1,18 @@ +contract C { + uint x; + modifier m() { + uint t; + assembly { + function f() -> x { x := 8 } + t := f() + } + x = t; + _; + } + function f() m m public returns (uint r) { + assembly { function f() -> x { x := 1 } r := f() } + } + function g() m m public returns (uint r) { + assembly { function f() -> x { x := 2 } r := f() } + } +} \ No newline at end of file diff --git a/test/cmdlineTests/inline_assembly_function_name_clash/output b/test/cmdlineTests/inline_assembly_function_name_clash/output new file mode 100644 index 0000000000..00192f8f44 --- /dev/null +++ b/test/cmdlineTests/inline_assembly_function_name_clash/output @@ -0,0 +1,168 @@ +{ + "contracts": + { + "inline_assembly_function_name_clash/input.sol:C": + { + "function-debug-runtime": + { + "abi_decode_tuple_": + { + "entryPoint": 216, + "parameterSlots": 2, + "returnSlots": 0 + }, + "abi_encode_t_uint256_to_t_uint256_fromStack": + { + "entryPoint": 250, + "parameterSlots": 2, + "returnSlots": 0 + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack": + { + "entryPoint": 265, + "parameterSlots": 2, + "returnSlots": 1 + }, + "allocate_unbounded": + { + "entryPoint": 196, + "parameterSlots": 0, + "returnSlots": 1 + }, + "cleanup_t_uint256": + { + "entryPoint": 240, + "parameterSlots": 1, + "returnSlots": 1 + }, + "convert_t_uint256_to_t_uint256": + { + "entryPoint": 391, + "parameterSlots": 1, + "returnSlots": 1 + }, + "fun_f_25": + { + "entryPoint": 658, + "id": 25, + "parameterSlots": 0, + "returnSlots": 1 + }, + "fun_f_25_inner": + { + "entryPoint": 624, + "parameterSlots": 1, + "returnSlots": 1 + }, + "fun_g_36": + { + "entryPoint": 874, + "id": 36, + "parameterSlots": 0, + "returnSlots": 1 + }, + "fun_g_36_inner": + { + "entryPoint": 840, + "parameterSlots": 1, + "returnSlots": 1 + }, + "identity": + { + "entryPoint": 381, + "parameterSlots": 1, + "returnSlots": 1 + }, + "modifier_m_17": + { + "entryPoint": 470, + "id": 14, + "parameterSlots": 1, + "returnSlots": 1 + }, + "modifier_m_19": + { + "entryPoint": 547, + "id": 14, + "parameterSlots": 1, + "returnSlots": 1 + }, + "modifier_m_28": + { + "entryPoint": 686, + "id": 14, + "parameterSlots": 1, + "returnSlots": 1 + }, + "modifier_m_30": + { + "entryPoint": 763, + "id": 14, + "parameterSlots": 1, + "returnSlots": 1 + }, + "prepare_store_t_uint256": + { + "entryPoint": 425, + "parameterSlots": 1, + "returnSlots": 1 + }, + "revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74": + { + "entryPoint": 292, + "parameterSlots": 0, + "returnSlots": 0 + }, + "revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb": + { + "entryPoint": 206, + "parameterSlots": 0, + "returnSlots": 0 + }, + "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": + { + "entryPoint": 211, + "parameterSlots": 0, + "returnSlots": 0 + }, + "shift_left_0": + { + "entryPoint": 302, + "parameterSlots": 1, + "returnSlots": 1 + }, + "shift_right_224_unsigned": + { + "entryPoint": 183, + "parameterSlots": 1, + "returnSlots": 1 + }, + "update_byte_slice_32_shift_0": + { + "entryPoint": 315, + "parameterSlots": 2, + "returnSlots": 1 + }, + "update_storage_value_offset_0t_uint256_to_t_uint256": + { + "entryPoint": 435, + "parameterSlots": 2, + "returnSlots": 0 + }, + "usr$f": + { + "entryPoint": 493, + "parameterSlots": 0, + "returnSlots": 1 + }, + "zero_value_for_split_t_uint256": + { + "entryPoint": 297, + "parameterSlots": 0, + "returnSlots": 1 + } + } + } + }, + "version": "" +} diff --git a/test/cmdlineTests/yul_function_name_clashes/args b/test/cmdlineTests/yul_function_name_clashes/args new file mode 100644 index 0000000000..903cc6eb41 --- /dev/null +++ b/test/cmdlineTests/yul_function_name_clashes/args @@ -0,0 +1 @@ +--strict-assembly --debug-info none \ No newline at end of file diff --git a/test/cmdlineTests/yul_function_name_clashes/err b/test/cmdlineTests/yul_function_name_clashes/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/yul_function_name_clashes/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/yul_function_name_clashes/input.yul b/test/cmdlineTests/yul_function_name_clashes/input.yul new file mode 100644 index 0000000000..0ede2d25e3 --- /dev/null +++ b/test/cmdlineTests/yul_function_name_clashes/input.yul @@ -0,0 +1,17 @@ +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) + } +} \ No newline at end of file diff --git a/test/cmdlineTests/yul_function_name_clashes/output b/test/cmdlineTests/yul_function_name_clashes/output new file mode 100644 index 0000000000..8a7bec7909 --- /dev/null +++ b/test/cmdlineTests/yul_function_name_clashes/output @@ -0,0 +1,66 @@ + +======= yul_function_name_clashes/input.yul (EVM) ======= + +Pretty printed source: +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) + } +} + + +Binary representation: +600080600f565b60008035905090565b60156006565b91506025565b6000602035905090565b602b601b565b90508082555050 + +Text representation: + 0x00 + dup1 + jump(tag_2) +tag_1: + 0x00 + dup1 + calldataload + swap1 + pop + swap1 + jump // out +tag_2: + tag_4 + tag_1 + jump // in +tag_4: + swap2 + pop + jump(tag_6) +tag_5: + 0x00 + 0x20 + calldataload + swap1 + pop + swap1 + jump // out +tag_6: + tag_8 + tag_5 + jump // in +tag_8: + swap1 + pop + dup1 + dup3 + sstore + pop + pop diff --git a/test/cmdlineTests/yul_function_name_clashes_different_params/args b/test/cmdlineTests/yul_function_name_clashes_different_params/args new file mode 100644 index 0000000000..2c89c24e0a --- /dev/null +++ b/test/cmdlineTests/yul_function_name_clashes_different_params/args @@ -0,0 +1 @@ +--strict-assembly diff --git a/test/cmdlineTests/yul_function_name_clashes_different_params/err b/test/cmdlineTests/yul_function_name_clashes_different_params/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/yul_function_name_clashes_different_params/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/yul_function_name_clashes_different_params/input.yul b/test/cmdlineTests/yul_function_name_clashes_different_params/input.yul new file mode 100644 index 0000000000..e27ca014ab --- /dev/null +++ b/test/cmdlineTests/yul_function_name_clashes_different_params/input.yul @@ -0,0 +1,17 @@ +object "object" { + code { + let a + let b + { + function z() -> y + { y := calldataload(0) } + a := z() + } + { + function z(r) -> y + { y := calldataload(r) } + b := z(0x70) + } + sstore(a, b) + } +} diff --git a/test/cmdlineTests/yul_function_name_clashes_different_params/output b/test/cmdlineTests/yul_function_name_clashes_different_params/output new file mode 100644 index 0000000000..f3dc843405 --- /dev/null +++ b/test/cmdlineTests/yul_function_name_clashes_different_params/output @@ -0,0 +1,93 @@ + +======= yul_function_name_clashes_different_params/input.yul (EVM) ======= + +Pretty printed source: +object "object" { + code { + let a + let b + { + function z() -> y + { y := calldataload(0) } + a := z() + } + { + function z(r) -> y + { y := calldataload(r) } + b := z(0x70) + } + sstore(a, b) + } +} + + +Binary representation: +600080600f565b60008035905090565b60156006565b91506026565b600081359050919050565b602e6070601b565b90508082555050 + +Text representation: + /* "yul_function_name_clashes_different_params/input.yul":37:42 */ + 0x00 + /* "yul_function_name_clashes_different_params/input.yul":51:56 */ + dup1 + /* "yul_function_name_clashes_different_params/input.yul":79:133 */ + jump(tag_2) +tag_1: + /* "yul_function_name_clashes_different_params/input.yul":95:96 */ + 0x00 + /* "yul_function_name_clashes_different_params/input.yul":129:130 */ + dup1 + /* "yul_function_name_clashes_different_params/input.yul":116:131 */ + calldataload + /* "yul_function_name_clashes_different_params/input.yul":111:131 */ + swap1 + pop + /* "yul_function_name_clashes_different_params/input.yul":79:133 */ + swap1 + jump // out +tag_2: + /* "yul_function_name_clashes_different_params/input.yul":151:154 */ + tag_4 + tag_1 + jump // in +tag_4: + /* "yul_function_name_clashes_different_params/input.yul":146:154 */ + swap2 + pop + /* "yul_function_name_clashes_different_params/input.yul":187:242 */ + jump(tag_6) +tag_5: + /* "yul_function_name_clashes_different_params/input.yul":204:205 */ + 0x00 + /* "yul_function_name_clashes_different_params/input.yul":238:239 */ + dup2 + /* "yul_function_name_clashes_different_params/input.yul":225:240 */ + calldataload + /* "yul_function_name_clashes_different_params/input.yul":220:240 */ + swap1 + pop + /* "yul_function_name_clashes_different_params/input.yul":187:242 */ + swap2 + swap1 + pop + jump // out +tag_6: + /* "yul_function_name_clashes_different_params/input.yul":260:267 */ + tag_8 + /* "yul_function_name_clashes_different_params/input.yul":262:266 */ + 0x70 + /* "yul_function_name_clashes_different_params/input.yul":260:267 */ + tag_5 + jump // in +tag_8: + /* "yul_function_name_clashes_different_params/input.yul":255:267 */ + swap1 + pop + /* "yul_function_name_clashes_different_params/input.yul":296:297 */ + dup1 + /* "yul_function_name_clashes_different_params/input.yul":293:294 */ + dup3 + /* "yul_function_name_clashes_different_params/input.yul":286:298 */ + sstore + /* "yul_function_name_clashes_different_params/input.yul":27:304 */ + pop + pop diff --git a/test/libsolidity/semanticTests/inlineAssembly/function_name_clash.sol b/test/libsolidity/semanticTests/inlineAssembly/function_name_clash.sol new file mode 100644 index 0000000000..21fbdb28af --- /dev/null +++ b/test/libsolidity/semanticTests/inlineAssembly/function_name_clash.sol @@ -0,0 +1,13 @@ +contract C { + function f() public pure returns (uint r) { + assembly { function f() -> x { x := 1 } r := f() } + } + function g() public pure returns (uint r) { + assembly { function f() -> x { x := 2 } r := f() } + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> 1 +// g() -> 2 From 2278673936f6f5aa8a243443d66680c9f6a9be0e Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 19 Oct 2021 10:54:54 -0400 Subject: [PATCH 0007/1748] Fix formatting --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index fadc252fc1..a7bfbbe448 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,7 +18,7 @@ and multi-signature wallets. When deploying contracts, you should use the latest released version of Solidity. Apart from exceptional cases, only the latest version receives -`security fixes`. +`security fixes `_. Furthermore, breaking changes as well as new features are introduced regularly. We currently use a 0.x version number `to indicate this fast pace of change `_. From 92f3d749e2077528a3625cc81a09a119fbb776a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 16:51:37 +0200 Subject: [PATCH 0008/1748] CI: Store yul-phaser as an artifact too --- .circleci/config.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a859b84640..266218bafc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -91,10 +91,14 @@ defaults: path: upload/ # compiled tool executable target - - artifacts_tools: &artifacts_tools + - artifact_solidity_upgrade: &artifact_solidity_upgrade path: build/tools/solidity-upgrade destination: solidity-upgrade + - artifact_yul_phaser: &artifact_yul_phaser + path: build/tools/yul-phaser + destination: yul-phaser + # compiled executable targets - artifacts_executables: &artifacts_executables root: build @@ -447,7 +451,8 @@ jobs: - checkout - run: *run_build - store_artifacts: *artifacts_solc - - store_artifacts: *artifacts_tools + - store_artifacts: *artifact_solidity_upgrade + - store_artifacts: *artifact_yul_phaser - persist_to_workspace: *artifacts_executables # x64 ASAN build, for testing for memory related bugs @@ -644,7 +649,8 @@ jobs: - /usr/local/Homebrew - run: *run_build - store_artifacts: *artifacts_solc - - store_artifacts: *artifacts_tools + - store_artifacts: *artifact_solidity_upgrade + - store_artifacts: *artifact_yul_phaser - persist_to_workspace: root: . paths: From 921d04451b823bc59f53b18be3476057f7a19c6b Mon Sep 17 00:00:00 2001 From: Gyeonghun Park Date: Fri, 22 Oct 2021 10:00:26 +0900 Subject: [PATCH 0009/1748] Fix typo in ir-breaking-changes.rst --- docs/ir/ir-breaking-changes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ir/ir-breaking-changes.rst b/docs/ir/ir-breaking-changes.rst index 8afbc58c3e..fb971410a8 100644 --- a/docs/ir/ir-breaking-changes.rst +++ b/docs/ir/ir-breaking-changes.rst @@ -268,7 +268,7 @@ In the new code generator, function pointers use the AST IDs of the functions as calls through function pointers always have to use an internal dispatch function that uses the ``switch`` statement to select the right function. -The ID ``0`` is reserved for uninitialized function pointers which then cause a panic in the disptach function when called. +The ID ``0`` is reserved for uninitialized function pointers which then cause a panic in the dispatch function when called. 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. From ab31437f2efdbbeb56e04796cef29bab087d14fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 20 Oct 2021 11:56:52 +0200 Subject: [PATCH 0010/1748] Add a PR check that runs hardhat tests using the built compiler binary --- .circleci/config.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index a859b84640..d086c672b5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -840,6 +840,32 @@ jobs: npm --version test/externalTests/solc-js/solc-js.sh /tmp/workspace/soljson.js $(cat /tmp/workspace/version.txt) + t_ems_ext_hardhat: + docker: + - image: circleci/node + environment: + TERM: xterm + HARDHAT_TESTS_SOLC_PATH: /tmp/workspace/soljson.js + steps: + - checkout + - attach_workspace: + at: /tmp/workspace + - run: git clone --depth 1 https://github.com/nomiclabs/hardhat.git + - run: + name: Install dependencies + command: | + cd hardhat + yarn + - run: + name: Run hardhat-core test suite + command: | + HARDHAT_TESTS_SOLC_VERSION=$(scripts/get_version.sh) + export HARDHAT_TESTS_SOLC_VERSION + + # NOTE: This is expected to work without running `yarn build` first. + cd hardhat/packages/hardhat-core + yarn test + t_ems_ext: parameters: project: @@ -1110,6 +1136,7 @@ workflows: # Emscripten build and tests that take 15 minutes or less - b_ems: *workflow_trigger_on_tags - t_ems_solcjs: *workflow_emscripten + - t_ems_ext_hardhat: *workflow_emscripten - t_ems_ext: <<: *workflow_emscripten From 0e71c12c56af1b6ca3bcbc5f0c7772ee89dfb490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 22 Oct 2021 18:02:12 +0200 Subject: [PATCH 0011/1748] CI: Refactor the gitter notification templates into a reusable command --- .circleci/config.yml | 74 +++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a859b84640..73f658b1e4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -30,6 +30,44 @@ parameters: orbs: win: circleci/windows@2.2.0 +commands: + gitter_notify: + description: "Posts a notification to the main room on Gitter (if not running on a PR)." + parameters: + event: + type: enum + enum: ["failure", "success"] + condition: + type: string + steps: + - run: + name: "Gitter notification" + command: | + [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ Nightly job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see ${CIRCLE_BUILD_URL} for details." + [[ "<< parameters.event >>" == "success" ]] && message=" ✅ Nightly job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see ${CIRCLE_BUILD_URL} for details." + + curl "https://api.gitter.im/v1/rooms/${GITTER_NOTIFY_ROOM_ID}/chatMessages" \ + --request POST \ + --include \ + --header "Content-Type: application/json" \ + --header "Accept: application/json" \ + --header "Authorization: Bearer ${GITTER_API_TOKEN}" \ + --data "{\"text\":\"${message}\"}" + + gitter_notify_failure: + description: "Posts a failure notification to the main room on Gitter (if not running on a PR)." + steps: + - gitter_notify: + event: failure + condition: on_fail + + gitter_notify_success: + description: "Posts a success notification to the main room on Gitter (if not running on a PR)." + steps: + - gitter_notify: + event: success + condition: on_success + defaults: # -------------------------------------------------------------------------- @@ -263,28 +301,6 @@ defaults: requires: - b_win_release - # -------------------------------------------------------------------------- - # Notification Templates - - gitter_notify_failure: &gitter_notify_failure - name: Gitter notify failure - command: >- - curl -X POST -i - -i -H "Content-Type: application/json" - -H "Accept: application/json" - -H "Authorization: Bearer $GITTER_API_TOKEN" "https://api.gitter.im/v1/rooms/$GITTER_NOTIFY_ROOM_ID/chatMessages" - -d '{"text":" ❌ Nightly job **'$CIRCLE_JOB'** failed on **'$CIRCLE_BRANCH'**. Please see '$CIRCLE_BUILD_URL' for details."}' - when: on_fail - - - gitter_notify_success: &gitter_notify_success - name: Gitter notify success - command: >- - curl -X POST -i - -i -H "Content-Type: application/json" - -H "Accept: application/json" - -H "Authorization: Bearer $GITTER_API_TOKEN" "https://api.gitter.im/v1/rooms/$GITTER_NOTIFY_ROOM_ID/chatMessages" - -d '{"text":" ✅ Nightly job **'$CIRCLE_JOB'** succeeded on **'$CIRCLE_BRANCH'**. Please see '$CIRCLE_BUILD_URL' for details."}' - when: on_success - # ----------------------------------------------------------------------------------------------- jobs: @@ -502,7 +518,7 @@ jobs: steps: - checkout - run: *run_build - - run: *gitter_notify_failure + - gitter_notify_failure - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables @@ -595,8 +611,8 @@ jobs: git clone https://github.com/ethereum/solidity-fuzzing-corpus /tmp/solidity-fuzzing-corpus mkdir -p test_results scripts/regressions.py -o test_results - - run: *gitter_notify_failure - - run: *gitter_notify_success + - gitter_notify_failure + - gitter_notify_success - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results @@ -807,7 +823,7 @@ jobs: - when: condition: true <<: *steps_soltest - - run: *gitter_notify_failure + - gitter_notify_failure t_ubu_ubsan_clang_cli: docker: @@ -816,7 +832,7 @@ jobs: - when: condition: true <<: *steps_cmdline_tests - - run: *gitter_notify_failure + - gitter_notify_failure t_ems_solcjs: docker: @@ -874,8 +890,8 @@ jobs: - when: condition: <> steps: - - run: *gitter_notify_failure - - run: *gitter_notify_success + - gitter_notify_failure + - gitter_notify_success b_win: &b_win executor: From a4fce301df22fb41dfe9410d987640e1c08b5b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 22 Oct 2021 20:47:25 +0200 Subject: [PATCH 0012/1748] CI: Use markdown link syntax in gitter messages --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 73f658b1e4..1c359ac812 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -43,8 +43,8 @@ commands: - run: name: "Gitter notification" command: | - [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ Nightly job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see ${CIRCLE_BUILD_URL} for details." - [[ "<< parameters.event >>" == "success" ]] && message=" ✅ Nightly job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see ${CIRCLE_BUILD_URL} for details." + [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ Nightly job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." + [[ "<< parameters.event >>" == "success" ]] && message=" ✅ Nightly job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." curl "https://api.gitter.im/v1/rooms/${GITTER_NOTIFY_ROOM_ID}/chatMessages" \ --request POST \ From 3387e134d79aa5850042a1c468c0e3b701930463 Mon Sep 17 00:00:00 2001 From: Adam Bliss Date: Sun, 24 Oct 2021 08:22:34 -0400 Subject: [PATCH 0013/1748] Fix typo compiler->constructor. --- docs/control-structures.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 1de35cf6bc..49e66537d3 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -288,7 +288,7 @@ which only need to be created if there is a dispute. re-created at the same address after having been destroyed. Yet, it is possible for that newly created contract to have a different deployed bytecode even though the creation bytecode has been the same (which is a requirement because - otherwise the address would change). This is due to the fact that the compiler + otherwise the address would change). This is due to the fact that the constructor can query external state that might have changed between the two creations and incorporate that into the deployed bytecode before it is stored. From cf005368d801ac54c76da071b21d023ed8dcadc2 Mon Sep 17 00:00:00 2001 From: shikharvashistha Date: Fri, 24 Sep 2021 04:25:20 +0000 Subject: [PATCH 0014/1748] Added different colors for warning & error Co-authored-by: shikharvashistha Co-authored-by: cameel --- Changelog.md | 1 + liblangutil/Exceptions.cpp | 15 +++++++++++++++ liblangutil/Exceptions.h | 2 ++ liblangutil/SourceReferenceFormatter.cpp | 21 +++++++++++++++++---- liblangutil/SourceReferenceFormatter.h | 2 +- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/Changelog.md b/Changelog.md index 69c3573fcb..2ab1bb0377 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Language Features: Compiler Features: * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. + * Commandline Interface: Use different colors when printing errors, warnings and infos. * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. * Standard JSON: Add ``settings.debug.debugInfo`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. diff --git a/liblangutil/Exceptions.cpp b/liblangutil/Exceptions.cpp index 34aa698033..a410a98635 100644 --- a/liblangutil/Exceptions.cpp +++ b/liblangutil/Exceptions.cpp @@ -23,6 +23,9 @@ #include +#include +#include + using namespace std; using namespace solidity; using namespace solidity::langutil; @@ -71,3 +74,15 @@ Error::Error( if (!_description.empty()) *this << util::errinfo_comment(_description); } + +optional Error::severityFromString(string _input) +{ + boost::algorithm::to_lower(_input); + boost::algorithm::trim(_input); + + for (Severity severity: {Severity::Error, Severity::Warning, Severity::Info}) + if (_input == formatErrorSeverityLowercase(severity)) + return severity; + + return nullopt; +} diff --git a/liblangutil/Exceptions.h b/liblangutil/Exceptions.h index 6946ff463d..0c8f03cb94 100644 --- a/liblangutil/Exceptions.h +++ b/liblangutil/Exceptions.h @@ -258,6 +258,8 @@ class Error: virtual public util::Exception solAssert(false, ""); } + static std::optional severityFromString(std::string _input); + private: ErrorId m_errorId; Type m_type; diff --git a/liblangutil/SourceReferenceFormatter.cpp b/liblangutil/SourceReferenceFormatter.cpp index 623e13dd1a..0edd551b8b 100644 --- a/liblangutil/SourceReferenceFormatter.cpp +++ b/liblangutil/SourceReferenceFormatter.cpp @@ -65,9 +65,21 @@ AnsiColorized SourceReferenceFormatter::frameColored() const return AnsiColorized(m_stream, m_colored, {BOLD, BLUE}); } -AnsiColorized SourceReferenceFormatter::errorColored() const +AnsiColorized SourceReferenceFormatter::errorColored(optional _severity) const { - return AnsiColorized(m_stream, m_colored, {BOLD, RED}); + // We used to color messages of any severity as errors so this seems like a good default + // for cases where severity cannot be determined. + char const* textColor = RED; + + if (_severity.has_value()) + switch (_severity.value()) + { + case Error::Severity::Error: textColor = RED; break; + case Error::Severity::Warning: textColor = YELLOW; break; + case Error::Severity::Info: textColor = WHITE; break; + } + + return AnsiColorized(m_stream, m_colored, {BOLD, textColor}); } AnsiColorized SourceReferenceFormatter::messageColored() const @@ -164,9 +176,10 @@ void SourceReferenceFormatter::printSourceLocation(SourceReference const& _ref) void SourceReferenceFormatter::printExceptionInformation(SourceReferenceExtractor::Message const& _msg) { // exception header line - errorColored() << _msg.severity; + optional severity = Error::severityFromString(_msg.severity); + errorColored(severity) << _msg.severity; if (m_withErrorIds && _msg.errorId.has_value()) - errorColored() << " (" << _msg.errorId.value().error << ")"; + errorColored(severity) << " (" << _msg.errorId.value().error << ")"; messageColored() << ": " << _msg.primary.message << '\n'; printSourceLocation(_msg.primary); diff --git a/liblangutil/SourceReferenceFormatter.h b/liblangutil/SourceReferenceFormatter.h index 5bac03a9af..e18400b60a 100644 --- a/liblangutil/SourceReferenceFormatter.h +++ b/liblangutil/SourceReferenceFormatter.h @@ -87,7 +87,7 @@ class SourceReferenceFormatter private: util::AnsiColorized normalColored() const; util::AnsiColorized frameColored() const; - util::AnsiColorized errorColored() const; + util::AnsiColorized errorColored(std::optional _severity) const; util::AnsiColorized messageColored() const; util::AnsiColorized secondaryColored() const; util::AnsiColorized highlightColored() const; From cc80f5e99245ec4789621cfabf2a122520a6a246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Oct 2021 10:40:45 +0200 Subject: [PATCH 0015/1748] Add missing condition to gitter_notify command --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7344d12916..00c7223d5e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,6 +42,7 @@ commands: steps: - run: name: "Gitter notification" + when: << parameters.condition >> command: | [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ Nightly job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." [[ "<< parameters.event >>" == "success" ]] && message=" ✅ Nightly job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." From fa48abf4f19b033a335107e970211fb4c9fccdad Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:42:05 +0200 Subject: [PATCH 0016/1748] Add new info functions --- liblangutil/ErrorReporter.cpp | 5 +++++ liblangutil/ErrorReporter.h | 2 ++ liblangutil/UniqueErrorReporter.h | 14 ++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/liblangutil/ErrorReporter.cpp b/liblangutil/ErrorReporter.cpp index 02487034ac..f99247b328 100644 --- a/liblangutil/ErrorReporter.cpp +++ b/liblangutil/ErrorReporter.cpp @@ -261,3 +261,8 @@ void ErrorReporter::info( { error(_error, Error::Type::Info, _location, _description); } + +void ErrorReporter::info(ErrorId _error, string const& _description) +{ + error(_error, Error::Type::Info, SourceLocation(), _description); +} diff --git a/liblangutil/ErrorReporter.h b/liblangutil/ErrorReporter.h index 6f91f0713b..67fc76e831 100644 --- a/liblangutil/ErrorReporter.h +++ b/liblangutil/ErrorReporter.h @@ -72,6 +72,8 @@ class ErrorReporter std::string const& _description ); + void info(ErrorId _error, std::string const& _description); + void declarationError( ErrorId _error, SourceLocation const& _location, diff --git a/liblangutil/UniqueErrorReporter.h b/liblangutil/UniqueErrorReporter.h index 8867205681..fd91b87dc6 100644 --- a/liblangutil/UniqueErrorReporter.h +++ b/liblangutil/UniqueErrorReporter.h @@ -61,6 +61,20 @@ class UniqueErrorReporter m_errorReporter.warning(_error, _description); } + void info(ErrorId _error, SourceLocation const& _location, std::string const& _description) + { + if (!seen(_error, _location, _description)) + { + m_errorReporter.info(_error, _location, _description); + markAsSeen(_error, _location, _description); + } + } + + void info(ErrorId _error, std::string const& _description) + { + m_errorReporter.info(_error, _description); + } + bool seen(ErrorId _error, SourceLocation const& _location, std::string const& _description) const { if (m_seenErrors.count({_error, _location})) From 9a87680d21668e37a0d3acbf160c760e8177d4af Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:44:33 +0200 Subject: [PATCH 0017/1748] Add invariant to the solver results --- libsmtutil/CHCSmtLib2Interface.cpp | 5 ++--- libsmtutil/CHCSmtLib2Interface.h | 4 +++- libsmtutil/CHCSolverInterface.h | 4 ++-- libsmtutil/Z3CHCInterface.cpp | 10 +++++----- libsmtutil/Z3CHCInterface.h | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/libsmtutil/CHCSmtLib2Interface.cpp b/libsmtutil/CHCSmtLib2Interface.cpp index 48fdbd3281..630eb06193 100644 --- a/libsmtutil/CHCSmtLib2Interface.cpp +++ b/libsmtutil/CHCSmtLib2Interface.cpp @@ -87,7 +87,7 @@ void CHCSmtLib2Interface::addRule(Expression const& _expr, std::string const& /* ); } -pair CHCSmtLib2Interface::query(Expression const& _block) +tuple CHCSmtLib2Interface::query(Expression const& _block) { string accumulated{}; swap(m_accumulatedOutput, accumulated); @@ -118,8 +118,7 @@ pair CHCSmtLib2Interface::query(Expre else result = CheckResult::ERROR; - // TODO collect invariants or counterexamples. - return {result, {}}; + return {result, Expression(true), {}}; } void CHCSmtLib2Interface::declareVariable(string const& _name, SortPointer const& _sort) diff --git a/libsmtutil/CHCSmtLib2Interface.h b/libsmtutil/CHCSmtLib2Interface.h index 460895e3b3..a7dfb76928 100644 --- a/libsmtutil/CHCSmtLib2Interface.h +++ b/libsmtutil/CHCSmtLib2Interface.h @@ -44,7 +44,9 @@ class CHCSmtLib2Interface: public CHCSolverInterface void addRule(Expression const& _expr, std::string const& _name) override; - std::pair query(Expression const& _expr) override; + /// 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; void declareVariable(std::string const& _name, SortPointer const& _sort) override; diff --git a/libsmtutil/CHCSolverInterface.h b/libsmtutil/CHCSolverInterface.h index 2032553451..8385c1c401 100644 --- a/libsmtutil/CHCSolverInterface.h +++ b/libsmtutil/CHCSolverInterface.h @@ -54,8 +54,8 @@ class CHCSolverInterface }; /// Takes a function application _expr and checks for reachability. - /// @returns solving result and a counterexample graph, if possible. - virtual std::pair query( + /// @returns solving result, an invariant, and counterexample graph, if possible. + virtual std::tuple query( Expression const& _expr ) = 0; diff --git a/libsmtutil/Z3CHCInterface.cpp b/libsmtutil/Z3CHCInterface.cpp index 1196b27ff8..82dca48788 100644 --- a/libsmtutil/Z3CHCInterface.cpp +++ b/libsmtutil/Z3CHCInterface.cpp @@ -77,7 +77,7 @@ void Z3CHCInterface::addRule(Expression const& _expr, string const& _name) } } -pair Z3CHCInterface::query(Expression const& _expr) +tuple Z3CHCInterface::query(Expression const& _expr) { CheckResult result; try @@ -93,15 +93,15 @@ pair Z3CHCInterface::query(Expression if (m_version >= tuple(4, 8, 8, 0)) { auto proof = m_solver.get_answer(); - return {result, cexGraph(proof)}; + return {result, Expression(true), cexGraph(proof)}; } break; } case z3::check_result::unsat: { result = CheckResult::UNSATISFIABLE; - // TODO retrieve invariants. - break; + auto invariants = m_z3Interface->fromZ3Expr(m_solver.get_answer()); + return {result, move(invariants), {}}; } case z3::check_result::unknown: { @@ -125,7 +125,7 @@ pair Z3CHCInterface::query(Expression result = CheckResult::ERROR; } - return {result, {}}; + return {result, Expression(true), {}}; } void Z3CHCInterface::setSpacerOptions(bool _preProcessing) diff --git a/libsmtutil/Z3CHCInterface.h b/libsmtutil/Z3CHCInterface.h index a0e4bfa671..5a768f65cb 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::pair query(Expression const& _expr) override; + std::tuple query(Expression const& _expr) override; Z3Interface* z3Interface() const { return m_z3Interface.get(); } From 1d659777699bf7f5e22526334e7ae1d46e0b4715 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:45:15 +0200 Subject: [PATCH 0018/1748] Adjust Z3Interface::fromZ3 for the extra cases --- libsmtutil/SolverInterface.h | 60 ++++++++++++++++++++++++++++++++++++ libsmtutil/Z3Interface.cpp | 46 +++++++++++++++++++++------ 2 files changed, 97 insertions(+), 9 deletions(-) diff --git a/libsmtutil/SolverInterface.h b/libsmtutil/SolverInterface.h index 87ee78013b..ca4c497ded 100644 --- a/libsmtutil/SolverInterface.h +++ b/libsmtutil/SolverInterface.h @@ -23,7 +23,9 @@ #include #include +#include +#include #include #include @@ -305,6 +307,64 @@ class Expression ); } + static bool sameSort(std::vector const& _args) + { + if (_args.empty()) + return true; + + auto sort = _args.front().sort; + return ranges::all_of( + _args, + [&](auto const& _expr){ return _expr.sort->kind == sort->kind; } + ); + } + + static Expression mkAnd(std::vector _args) + { + smtAssert(!_args.empty(), ""); + smtAssert(sameSort(_args), ""); + + auto sort = _args.front().sort; + if (sort->kind == Kind::BitVector) + return Expression("bvand", std::move(_args), sort); + + smtAssert(sort->kind == Kind::Bool, ""); + return Expression("and", std::move(_args), Kind::Bool); + } + + static Expression mkOr(std::vector _args) + { + smtAssert(!_args.empty(), ""); + smtAssert(sameSort(_args), ""); + + auto sort = _args.front().sort; + if (sort->kind == Kind::BitVector) + return Expression("bvor", std::move(_args), sort); + + smtAssert(sort->kind == Kind::Bool, ""); + return Expression("or", std::move(_args), Kind::Bool); + } + + static Expression mkPlus(std::vector _args) + { + smtAssert(!_args.empty(), ""); + smtAssert(sameSort(_args), ""); + + auto sort = _args.front().sort; + smtAssert(sort->kind == Kind::BitVector || sort->kind == Kind::Int, ""); + return Expression("+", std::move(_args), sort); + } + + static Expression mkMul(std::vector _args) + { + smtAssert(!_args.empty(), ""); + smtAssert(sameSort(_args), ""); + + auto sort = _args.front().sort; + smtAssert(sort->kind == Kind::BitVector || sort->kind == Kind::Int, ""); + return Expression("*", std::move(_args), sort); + } + friend Expression operator!(Expression _a) { if (_a.sort->kind == Kind::BitVector) diff --git a/libsmtutil/Z3Interface.cpp b/libsmtutil/Z3Interface.cpp index 03105a172c..3a5c75bf32 100644 --- a/libsmtutil/Z3Interface.cpp +++ b/libsmtutil/Z3Interface.cpp @@ -279,6 +279,19 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr) if (_expr.is_const() || _expr.is_var()) return Expression(_expr.to_string(), {}, sort); + if (_expr.is_quantifier()) + { + 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(), ""); vector arguments; for (unsigned i = 0; i < _expr.num_args(); ++i) @@ -290,33 +303,44 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr) else if (_expr.is_not()) return !arguments[0]; else if (_expr.is_and()) - return arguments[0] && arguments[1]; + return Expression::mkAnd(arguments); else if (_expr.is_or()) - return arguments[0] || arguments[1]; + 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_ULEQ || kind == Z3_OP_SLEQ) + 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_UGEQ || kind == Z3_OP_SGEQ) + 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 arguments[0] + arguments[1]; + 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 arguments[0] * arguments[1]; + 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_BNOT) + return !arguments[0]; else if (kind == Z3_OP_BSHL) return arguments[0] << arguments[1]; else if (kind == Z3_OP_BLSHR) @@ -324,9 +348,11 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr) else if (kind == Z3_OP_BASHR) return Expression::ashr(arguments[0], arguments[1]); else if (kind == Z3_OP_INT2BV) - smtAssert(false, ""); + return Expression::int2bv(arguments[0], _expr.get_sort().bv_size()); else if (kind == Z3_OP_BV2INT) - smtAssert(false, ""); + 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) @@ -342,7 +368,9 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr) return Expression::tuple_constructor(Expression(sortSort), arguments); } else if (kind == Z3_OP_DT_ACCESSOR) - smtAssert(false, ""); + 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) return Expression(_expr.decl().name().str(), arguments, fromZ3Sort(_expr.get_sort())); From ce72d7cd262478871a9dd199681a005f00f0f8bb Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:46:45 +0200 Subject: [PATCH 0019/1748] Add ExpressionFormatter which translates an smtutil::Expression into a Solidity-like expression string --- libsolidity/formal/ExpressionFormatter.cpp | 184 +++++++++++++++++++++ libsolidity/formal/ExpressionFormatter.h | 41 +++++ 2 files changed, 225 insertions(+) create mode 100644 libsolidity/formal/ExpressionFormatter.cpp create mode 100644 libsolidity/formal/ExpressionFormatter.h diff --git a/libsolidity/formal/ExpressionFormatter.cpp b/libsolidity/formal/ExpressionFormatter.cpp new file mode 100644 index 0000000000..2591328f84 --- /dev/null +++ b/libsolidity/formal/ExpressionFormatter.cpp @@ -0,0 +1,184 @@ +/* + 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 + +using namespace std; +using boost::algorithm::starts_with; +using namespace solidity; +using namespace solidity::util; +using namespace solidity::smtutil; +using namespace solidity::frontend::smt; + +namespace solidity::frontend::smt +{ + +namespace +{ + +string formatDatatypeAccessor(smtutil::Expression const& _expr, vector const& _args) +{ + auto const& op = _expr.name; + + // This is the most complicated part of the translation. + // Datatype accessor means access to a field of a datatype. + // In our encoding, datatypes are used to encode: + // - arrays/mappings as the tuple (array, length) + // - structs as the tuple (, ..., ) + // - hash and signature functions as the tuple (keccak256, sha256, ripemd160, ecrecover), + // where each element is an array emulating an UF + // - abi.* functions as the tuple (, ..., ). + if (op == "dt_accessor_keccak256") + return "keccak256"; + if (op == "dt_accessor_sha256") + return "sha256"; + if (op == "dt_accessor_ripemd160") + return "ripemd160"; + if (op == "dt_accessor_ecrecover") + return "ecrecover"; + + string accessorStr = "accessor_"; + // Struct members have suffix "accessor_". + string type = op.substr(op.rfind(accessorStr) + accessorStr.size()); + solAssert(_expr.arguments.size() == 1, ""); + + if (type == "length") + return _args.at(0) + ".length"; + if (type == "array") + return _args.at(0); + + if ( + starts_with(type, "block") || + starts_with(type, "msg") || + starts_with(type, "tx") || + starts_with(type, "abi") + ) + return type; + + if (starts_with(type, "t_function_abi")) + return type; + + return _args.at(0) + "." + type; +} + +string formatGenericOp(smtutil::Expression const& _expr, vector const& _args) +{ + return _expr.name + "(" + boost::algorithm::join(_args, ", ") + ")"; +} + +string formatInfixOp(string const& _op, vector const& _args) +{ + return "(" + boost::algorithm::join(_args, " " + _op + " ") + ")"; +} + +string formatArrayOp(smtutil::Expression const& _expr, vector const& _args) +{ + if (_expr.name == "select") + { + auto const& a0 = _args.at(0); + static set const ufs{"keccak256", "sha256", "ripemd160", "ecrecover"}; + if (ufs.count(a0) || starts_with(a0, "t_function_abi")) + return _args.at(0) + "(" + _args.at(1) + ")"; + return _args.at(0) + "[" + _args.at(1) + "]"; + } + if (_expr.name == "store") + return "(" + _args.at(0) + "[" + _args.at(1) + "] := " + _args.at(2) + ")"; + return formatGenericOp(_expr, _args); +} + +string formatUnaryOp(smtutil::Expression const& _expr, vector const& _args) +{ + if (_expr.name == "not") + return "!" + _args.at(0); + // Other operators such as exists may end up here. + return formatGenericOp(_expr, _args); +} + +} + +smtutil::Expression substitute(smtutil::Expression _from, map const& _subst) +{ + // TODO For now we ignore nested quantifier expressions, + // but we should support them in the future. + if (_from.name == "forall" || _from.name == "exists") + return smtutil::Expression(true); + if (_subst.count(_from.name)) + _from.name = _subst.at(_from.name); + for (auto& arg: _from.arguments) + arg = substitute(arg, _subst); + return _from; +} + +string toSolidityStr(smtutil::Expression const& _expr) +{ + auto const& op = _expr.name; + + auto const& args = _expr.arguments; + auto strArgs = util::applyMap(args, [](auto const& _arg) { return toSolidityStr(_arg); }); + + // Constant or variable. + if (args.empty()) + return op; + + if (starts_with(op, "dt_accessor")) + return formatDatatypeAccessor(_expr, strArgs); + + // Infix operators with format replacements. + static map const infixOps{ + {"and", "&&"}, + {"or", "||"}, + {"implies", "=>"}, + {"=", "="}, + {">", ">"}, + {">=", ">="}, + {"<", "<"}, + {"<=", "<="}, + {"+", "+"}, + {"-", "-"}, + {"*", "*"}, + {"/", "/"}, + {"div", "/"}, + {"mod", "%"} + }; + // Some of these (and, or, +, *) may have >= 2 arguments from z3. + if (infixOps.count(op)) + return formatInfixOp(infixOps.at(op), strArgs); + + static set const arrayOps{"select", "store", "const_array"}; + if (arrayOps.count(op)) + return formatArrayOp(_expr, strArgs); + + if (args.size() == 1) + return formatUnaryOp(_expr, strArgs); + + // Other operators such as bv2int, int2bv may end up here. + return op + "(" + boost::algorithm::join(strArgs, ", ") + ")"; +} + +} diff --git a/libsolidity/formal/ExpressionFormatter.h b/libsolidity/formal/ExpressionFormatter.h new file mode 100644 index 0000000000..3efbeb781f --- /dev/null +++ b/libsolidity/formal/ExpressionFormatter.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 + +/** + * Formats SMT expressions into Solidity-like strings. + */ + +#include + +#include +#include + +namespace solidity::frontend::smt +{ + +/// @returns another smtutil::Expressions where every term in _from +/// may be replaced if it is in the substitution map _subst. +smtutil::Expression substitute(smtutil::Expression _from, std::map const& _subst); + +/// @returns a Solidity-like expression string built from _expr. +/// This is done at best-effort and is not guaranteed to always create a perfect Solidity expression string. +std::string toSolidityStr(smtutil::Expression const& _expr); + +} From 9bcd2c18e42d29b4698103493ced4099e156ec5c Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:48:15 +0200 Subject: [PATCH 0020/1748] Add expression substitution to Predicate --- libsolidity/formal/Predicate.cpp | 52 ++++++++++++++++++++++++++++++++ libsolidity/formal/Predicate.h | 21 +++++++++++++ 2 files changed, 73 insertions(+) diff --git a/libsolidity/formal/Predicate.cpp b/libsolidity/formal/Predicate.cpp index 23aa7590e0..6e0eb4f3b9 100644 --- a/libsolidity/formal/Predicate.cpp +++ b/libsolidity/formal/Predicate.cpp @@ -26,10 +26,13 @@ #include #include +#include + #include #include using namespace std; +using boost::algorithm::starts_with; using namespace solidity; using namespace solidity::smtutil; using namespace solidity::frontend; @@ -198,6 +201,11 @@ bool Predicate::isInterface() const return m_type == PredicateType::Interface; } +bool Predicate::isNondetInterface() const +{ + return m_type == PredicateType::NondetInterface; +} + string Predicate::formatSummaryCall( vector const& _args, langutil::CharStreamProvider const& _charStreamProvider, @@ -418,6 +426,50 @@ pair>, vector> Predicate::lo return {formatExpressions(outValuesInScope, outTypes), localVarsInScope}; } +map Predicate::expressionSubstitution(smtutil::Expression const& _predExpr) const +{ + map subst; + string predName = functor().name; + + solAssert(contextContract(), ""); + auto const& stateVars = SMTEncoder::stateVariablesIncludingInheritedAndPrivate(*contextContract()); + + auto nArgs = _predExpr.arguments.size(); + + // The signature of an interface predicate is + // interface(this, abiFunctions, cryptoFunctions, blockchainState, stateVariables). + // An invariant for an interface predicate is a contract + // invariant over its state, for example `x <= 0`. + if (isInterface()) + { + solAssert(starts_with(predName, "interface"), ""); + subst[_predExpr.arguments.at(0).name] = "address(this)"; + solAssert(nArgs == stateVars.size() + 4, ""); + for (size_t i = nArgs - stateVars.size(); i < nArgs; ++i) + subst[_predExpr.arguments.at(i).name] = stateVars.at(i - 4)->name(); + } + // The signature of a nondet interface predicate is + // nondet_interface(error, this, abiFunctions, cryptoFunctions, blockchainState, stateVariables, blockchainState', stateVariables'). + // An invariant for a nondet interface predicate is a reentrancy property + // over the pre and post state variables of a contract, where pre state vars + // are represented by the variable's name and post state vars are represented + // by the primed variable's name, for example + // `(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 + 6, ""); + for (size_t i = nArgs - stateVars.size(), s = 0; i < nArgs; ++i, ++s) + subst[_predExpr.arguments.at(i).name] = 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(); + } + + return subst; +} + vector> Predicate::formatExpressions(vector const& _exprs, vector const& _types) const { solAssert(_exprs.size() == _types.size(), ""); diff --git a/libsolidity/formal/Predicate.h b/libsolidity/formal/Predicate.h index 7357c9beba..16af42f45f 100644 --- a/libsolidity/formal/Predicate.h +++ b/libsolidity/formal/Predicate.h @@ -21,6 +21,8 @@ #include #include +#include + #include #include @@ -143,6 +145,9 @@ class Predicate /// @returns true if this predicate represents an interface. bool isInterface() const; + /// @returns true if this predicate represents a nondeterministic interface. + bool isNondetInterface() const; + PredicateType type() const { return m_type; } /// @returns a formatted string representing a call to this predicate @@ -168,6 +173,10 @@ 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 + /// to a Solidity-like expression. + std::map expressionSubstitution(smtutil::Expression const& _predExpr) 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; @@ -208,4 +217,16 @@ class Predicate std::vector const m_scopeStack; }; +struct PredicateCompare +{ + bool operator()(Predicate const* lhs, Predicate const* rhs) const + { + // We cannot use m_node->id() because different predicates may + // represent the same program node. + // We use the symbolic name since it is unique per predicate and + // the order does not really matter. + return lhs->functor().name < rhs->functor().name; + } +}; + } From d554824f70ecef2d79442d655188c995f970a228 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:49:00 +0200 Subject: [PATCH 0021/1748] Add Invariants which traverses the proof and collects invariants for the given predicates --- libsolidity/formal/Invariants.cpp | 86 +++++++++++++++++++++++++++++++ libsolidity/formal/Invariants.h | 37 +++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 libsolidity/formal/Invariants.cpp create mode 100644 libsolidity/formal/Invariants.h diff --git a/libsolidity/formal/Invariants.cpp b/libsolidity/formal/Invariants.cpp new file mode 100644 index 0000000000..9dad0722cd --- /dev/null +++ b/libsolidity/formal/Invariants.cpp @@ -0,0 +1,86 @@ +/* + 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; +using boost::algorithm::starts_with; +using namespace solidity; +using namespace solidity::smtutil; +using namespace solidity::frontend::smt; + +namespace solidity::frontend::smt +{ + +map> collectInvariants( + smtutil::Expression const& _proof, + set const& _predicates, + ModelCheckerInvariants const& _invariantsSetting +) +{ + set targets; + if (_invariantsSetting.has(InvariantType::Contract)) + targets.insert("interface_"); + if (_invariantsSetting.has(InvariantType::Reentrancy)) + targets.insert("nondet_interface_"); + + map> equalities; + // Collect equalities where one of the sides is a predicate we're interested in. + 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, move(arg1)}}); + else if (starts_with(arg1.name, t)) + equalities.insert({arg1.name, {arg1, move(arg0)}}); + } + for (auto const& arg: _expr->arguments) + _addChild(&arg); + }); + + 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 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 new file mode 100644 index 0000000000..b6459fccd4 --- /dev/null +++ b/libsolidity/formal/Invariants.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 +#include + +#include +#include +#include + +namespace solidity::frontend::smt +{ + +std::map> collectInvariants( + smtutil::Expression const& _proof, + std::set const& _predicates, + ModelCheckerInvariants const& _invariantsSettings +); + +} From bc90533c93626b92598c19c249a84e77dfdc15da Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:50:00 +0200 Subject: [PATCH 0022/1748] Add invariants to ModelCheckerSettings --- libsolidity/formal/ModelCheckerSettings.cpp | 34 +++++++++++++++++++++ libsolidity/formal/ModelCheckerSettings.h | 27 ++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/libsolidity/formal/ModelCheckerSettings.cpp b/libsolidity/formal/ModelCheckerSettings.cpp index 207894d398..8fe3a21203 100644 --- a/libsolidity/formal/ModelCheckerSettings.cpp +++ b/libsolidity/formal/ModelCheckerSettings.cpp @@ -25,6 +25,40 @@ using namespace std; using namespace solidity; using namespace solidity::frontend; +map const ModelCheckerInvariants::validInvariants{ + {"contract", InvariantType::Contract}, + {"reentrancy", InvariantType::Reentrancy} +}; + +std::optional ModelCheckerInvariants::fromString(string const& _invs) +{ + set chosenInvs; + if (_invs == "default") + { + // The default is that no invariants are reported. + } + else if (_invs == "all") + for (auto&& v: validInvariants | ranges::views::values) + chosenInvs.insert(v); + else + for (auto&& t: _invs | ranges::views::split(',') | ranges::to>()) + { + if (!validInvariants.count(t)) + return {}; + chosenInvs.insert(validInvariants.at(t)); + } + + return ModelCheckerInvariants{chosenInvs}; +} + +bool ModelCheckerInvariants::setFromString(string const& _inv) +{ + if (!validInvariants.count(_inv)) + return false; + invariants.insert(validInvariants.at(_inv)); + return true; +} + using TargetType = VerificationTargetType; map const ModelCheckerTargets::targetStrings{ {"constantCondition", TargetType::ConstantCondition}, diff --git a/libsolidity/formal/ModelCheckerSettings.h b/libsolidity/formal/ModelCheckerSettings.h index a01985fcb1..5623b2a193 100644 --- a/libsolidity/formal/ModelCheckerSettings.h +++ b/libsolidity/formal/ModelCheckerSettings.h @@ -87,6 +87,31 @@ struct ModelCheckerEngine bool operator==(ModelCheckerEngine const& _other) const noexcept { return bmc == _other.bmc && chc == _other.chc; } }; +enum class InvariantType { Contract, Reentrancy }; + +struct ModelCheckerInvariants +{ + /// Adds the default targets, that is, all except underflow and overflow. + static ModelCheckerInvariants Default() { return *fromString("default"); } + /// Adds all targets, including underflow and overflow. + static ModelCheckerInvariants All() { return *fromString("all"); } + + static std::optional fromString(std::string const& _invs); + + bool has(InvariantType _inv) const { return invariants.count(_inv); } + + /// @returns true if the @p _target is valid, + /// and false otherwise. + bool setFromString(std::string const& _target); + + static std::map const validInvariants; + + bool operator!=(ModelCheckerInvariants const& _other) const noexcept { return !(*this == _other); } + bool operator==(ModelCheckerInvariants const& _other) const noexcept { return invariants == _other.invariants; } + + std::set invariants; +}; + enum class VerificationTargetType { ConstantCondition, Underflow, Overflow, UnderOverflow, DivByZero, Balance, Assert, PopEmptyArray, OutOfBounds }; struct ModelCheckerTargets @@ -123,6 +148,7 @@ struct ModelCheckerSettings /// might prefer the precise encoding. bool divModNoSlacks = false; ModelCheckerEngine engine = ModelCheckerEngine::None(); + ModelCheckerInvariants invariants = ModelCheckerInvariants::Default(); bool showUnproved = false; smtutil::SMTSolverChoice solvers = smtutil::SMTSolverChoice::All(); ModelCheckerTargets targets = ModelCheckerTargets::Default(); @@ -135,6 +161,7 @@ struct ModelCheckerSettings contracts == _other.contracts && divModNoSlacks == _other.divModNoSlacks && engine == _other.engine && + invariants == _other.invariants && showUnproved == _other.showUnproved && solvers == _other.solvers && targets == _other.targets && From 49e7627bd3d2aca5cb6b9ab9f20d8e3a1daa4db1 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:50:41 +0200 Subject: [PATCH 0023/1748] Use invariants in CHC --- libsolidity/CMakeLists.txt | 4 +++ libsolidity/formal/CHC.cpp | 68 +++++++++++++++++++++++++++++++------- libsolidity/formal/CHC.h | 9 +++-- 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index a1cb68c35c..7e3791eab0 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -108,6 +108,10 @@ set(sources formal/CHC.h formal/EncodingContext.cpp 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 f0072313b7..b75a975dfe 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -23,6 +23,7 @@ #endif #include +#include #include #include #include @@ -32,15 +33,17 @@ #include #include -#include - -#include -#include - #ifdef HAVE_Z3_DLOPEN #include #endif +#include + +#include +#include +#include +#include + #include #include @@ -971,6 +974,7 @@ void CHC::resetSourceAnalysis() m_safeTargets.clear(); m_unsafeTargets.clear(); m_unprovedTargets.clear(); + m_invariants.clear(); m_functionTargetIds.clear(); m_verificationTargets.clear(); m_queryPlaceholders.clear(); @@ -1128,8 +1132,8 @@ void CHC::defineInterfacesAndSummaries(SourceUnit const& _source) if (auto const* contract = dynamic_cast(node.get())) { string suffix = contract->name() + "_" + to_string(contract->id()); - m_interfaces[contract] = createSymbolicBlock(interfaceSort(*contract, state()), "interface_" + uniquePrefix() + "_" + suffix, PredicateType::Interface, contract); - m_nondetInterfaces[contract] = createSymbolicBlock(nondetInterfaceSort(*contract, state()), "nondet_interface_" + uniquePrefix() + "_" + suffix, PredicateType::NondetInterface, contract); + m_interfaces[contract] = createSymbolicBlock(interfaceSort(*contract, state()), "interface_" + uniquePrefix() + "_" + suffix, PredicateType::Interface, contract, contract); + m_nondetInterfaces[contract] = createSymbolicBlock(nondetInterfaceSort(*contract, state()), "nondet_interface_" + uniquePrefix() + "_" + suffix, PredicateType::NondetInterface, contract, contract); m_constructorSummaries[contract] = createConstructorBlock(*contract, "summary_constructor"); for (auto const* var: stateVariablesIncludingInheritedAndPrivate(*contract)) @@ -1527,11 +1531,12 @@ void CHC::addRule(smtutil::Expression const& _rule, string const& _ruleName) m_interface->addRule(_rule, _ruleName); } -pair CHC::query(smtutil::Expression const& _query, langutil::SourceLocation const& _location) +tuple CHC::query(smtutil::Expression const& _query, langutil::SourceLocation const& _location) { CheckResult result; + smtutil::Expression invariant(true); CHCSolverInterface::CexGraph cex; - tie(result, cex) = m_interface->query(_query); + tie(result, invariant, cex) = m_interface->query(_query); switch (result) { case CheckResult::SATISFIABLE: @@ -1546,8 +1551,9 @@ pair CHC::query(smtutil::Expression c spacer->setSpacerOptions(false); CheckResult resultNoOpt; + smtutil::Expression invariantNoOpt(true); CHCSolverInterface::CexGraph cexNoOpt; - tie(resultNoOpt, cexNoOpt) = m_interface->query(_query); + tie(resultNoOpt, invariantNoOpt, cexNoOpt) = m_interface->query(_query); if (resultNoOpt == CheckResult::SATISFIABLE) cex = move(cexNoOpt); @@ -1568,7 +1574,7 @@ pair CHC::query(smtutil::Expression c m_errorReporter.warning(1218_error, _location, "CHC: Error trying to invoke SMT solver."); break; } - return {result, cex}; + return {result, invariant, cex}; } void CHC::verificationTargetEncountered( @@ -1715,6 +1721,34 @@ void CHC::checkVerificationTargets() " Consider increasing the timeout per query." ); + if (!m_settings.invariants.invariants.empty()) + { + string msg; + for (auto pred: m_invariants | ranges::views::keys) + { + ASTNode const* node = pred->programNode(); + string what; + if (auto contract = dynamic_cast(node)) + what = contract->fullyQualifiedName(); + else + solAssert(false, ""); + + string invType; + if (pred->type() == PredicateType::Interface) + invType = "Contract invariant(s)"; + else if (pred->type() == PredicateType::NondetInterface) + invType = "Reentrancy property(ies)"; + else + solAssert(false, ""); + + msg += invType + " for " + what + ":\n"; + for (auto const& inv: m_invariants.at(pred)) + msg += inv + "\n"; + } + if (!msg.empty()) + m_errorReporter.info(1180_error, msg); + } + // There can be targets in internal functions that are not reachable from the external interface. // These are safe by definition and are not even checked by the CHC engine, but this information // must still be reported safe by the BMC engine. @@ -1748,9 +1782,19 @@ void CHC::checkAndReportTarget( createErrorBlock(); connectBlocks(_target.value, error(), _target.constraints); auto const& location = _target.errorNode->location(); - auto const& [result, model] = query(error(), location); + auto [result, invariant, model] = query(error(), location); if (result == CheckResult::UNSATISFIABLE) + { m_safeTargets[_target.errorNode].insert(_target.type); + set predicates; + for (auto const* pred: m_interfaces | ranges::views::values) + predicates.insert(pred); + for (auto const* pred: m_nondetInterfaces | ranges::views::values) + predicates.insert(pred); + map> invariants = collectInvariants(invariant, predicates, m_settings.invariants); + for (auto pred: invariants | ranges::views::keys) + m_invariants[pred] += move(invariants.at(pred)); + } else if (result == CheckResult::SATISFIABLE) { solAssert(!_satMsg.empty(), ""); diff --git a/libsolidity/formal/CHC.h b/libsolidity/formal/CHC.h index 24b27c55b9..d9e27a89cc 100644 --- a/libsolidity/formal/CHC.h +++ b/libsolidity/formal/CHC.h @@ -245,9 +245,9 @@ class CHC: public SMTEncoder //@{ /// Adds Horn rule to the solver. void addRule(smtutil::Expression const& _rule, std::string const& _ruleName); - /// @returns if query is unsatisfiable (safe). - /// @returns otherwise. - std::pair query(smtutil::Expression const& _query, langutil::SourceLocation const& _location); + /// @returns if query is unsatisfiable (safe). + /// @returns otherwise. + std::tuple query(smtutil::Expression const& _query, langutil::SourceLocation const& _location); void verificationTargetEncountered(ASTNode const* const _errorNode, VerificationTargetType _type, smtutil::Expression const& _errorCondition); @@ -378,6 +378,9 @@ class CHC: public SMTEncoder std::map, smt::EncodingContext::IdCompare> m_unsafeTargets; /// Targets not proved. std::map, smt::EncodingContext::IdCompare> m_unprovedTargets; + + /// Inferred invariants. + std::map, PredicateCompare> m_invariants; //@} /// Control-flow. From d419c30ca67e6a3a95a1ed646f14ea8cc11e551e Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 13 Oct 2021 16:21:12 +0200 Subject: [PATCH 0024/1748] Add errorCode list to invariants report --- libsolidity/formal/CHC.cpp | 14 ++++++++++++++ libsolidity/formal/ModelCheckerSettings.cpp | 11 +++++++++++ libsolidity/formal/ModelCheckerSettings.h | 2 ++ 3 files changed, 27 insertions(+) diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index b75a975dfe..bfdb0b4289 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #ifdef HAVE_Z3_DLOPEN @@ -1745,6 +1746,19 @@ void CHC::checkVerificationTargets() for (auto const& inv: m_invariants.at(pred)) msg += inv + "\n"; } + if (msg.find("") != string::npos) + { + set seenErrors; + msg += " = 0 -> no errors\n"; + for (auto const& target: verificationTargets) + if (!seenErrors.count(target.errorId)) + { + seenErrors.insert(target.errorId); + string loc = string(m_charStreamProvider.charStream(*target.errorNode->location().sourceName).text(target.errorNode->location())); + msg += " = " + to_string(target.errorId) + " -> " + ModelCheckerTargets::targetTypeToString.at(target.type) + " at " + loc + "\n"; + + } + } if (!msg.empty()) m_errorReporter.info(1180_error, msg); } diff --git a/libsolidity/formal/ModelCheckerSettings.cpp b/libsolidity/formal/ModelCheckerSettings.cpp index 8fe3a21203..274571a154 100644 --- a/libsolidity/formal/ModelCheckerSettings.cpp +++ b/libsolidity/formal/ModelCheckerSettings.cpp @@ -71,6 +71,17 @@ map const ModelCheckerTargets::targetStrings{ {"outOfBounds", TargetType::OutOfBounds} }; +map const ModelCheckerTargets::targetTypeToString{ + {TargetType::ConstantCondition, "Constant condition"}, + {TargetType::Underflow, "Underflow"}, + {TargetType::Overflow, "Overflow"}, + {TargetType::DivByZero, "Division by zero"}, + {TargetType::Balance, "Insufficient balance"}, + {TargetType::Assert, "Assertion failed"}, + {TargetType::PopEmptyArray, "Empty array pop"}, + {TargetType::OutOfBounds, "Out of bounds access"} +}; + std::optional ModelCheckerTargets::fromString(string const& _targets) { set chosenTargets; diff --git a/libsolidity/formal/ModelCheckerSettings.h b/libsolidity/formal/ModelCheckerSettings.h index 5623b2a193..3d137044a8 100644 --- a/libsolidity/formal/ModelCheckerSettings.h +++ b/libsolidity/formal/ModelCheckerSettings.h @@ -131,6 +131,8 @@ struct ModelCheckerTargets static std::map const targetStrings; + static std::map const targetTypeToString; + bool operator!=(ModelCheckerTargets const& _other) const noexcept { return !(*this == _other); } bool operator==(ModelCheckerTargets const& _other) const noexcept { return targets == _other.targets; } From 3118fb366656a4af2066ab75b77aaefcf2bee25e Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:51:22 +0200 Subject: [PATCH 0025/1748] Add invariants option to CLI and JSON --- libsolidity/interface/StandardCompiler.cpp | 23 +++++++++++++++++++++- solc/CommandLineParser.cpp | 21 ++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 66f5dc4e54..da28cf29f2 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -445,7 +445,7 @@ std::optional checkSettingsKeys(Json::Value const& _input) std::optional checkModelCheckerSettingsKeys(Json::Value const& _input) { - static set keys{"contracts", "divModNoSlacks", "engine", "showUnproved", "solvers", "targets", "timeout"}; + static set keys{"contracts", "divModNoSlacks", "engine", "invariants", "showUnproved", "solvers", "targets", "timeout"}; return checkKeys(_input, keys, "modelChecker"); } @@ -987,6 +987,27 @@ std::variant StandardCompiler: ret.modelCheckerSettings.engine = *engine; } + if (modelCheckerSettings.isMember("invariants")) + { + auto const& invariantsArray = modelCheckerSettings["invariants"]; + if (!invariantsArray.isArray()) + return formatFatalError("JSONError", "settings.modelChecker.invariants must be an array."); + + ModelCheckerInvariants invariants; + for (auto const& i: invariantsArray) + { + if (!i.isString()) + return formatFatalError("JSONError", "Every invariant type in settings.modelChecker.invariants must be a string."); + if (!invariants.setFromString(i.asString())) + return formatFatalError("JSONError", "Invalid model checker invariants requested."); + } + + if (invariants.invariants.empty()) + return formatFatalError("JSONError", "settings.modelChecker.invariants must be a non-empty array."); + + ret.modelCheckerSettings.invariants = invariants; + } + if (modelCheckerSettings.isMember("showUnproved")) { auto const& showUnproved = modelCheckerSettings["showUnproved"]; diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 6b1fc1526e..22d92d4630 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -78,6 +78,7 @@ static string const g_strMetadataLiteral = "metadata-literal"; static string const g_strModelCheckerContracts = "model-checker-contracts"; static string const g_strModelCheckerDivModNoSlacks = "model-checker-div-mod-no-slacks"; static string const g_strModelCheckerEngine = "model-checker-engine"; +static string const g_strModelCheckerInvariants = "model-checker-invariants"; static string const g_strModelCheckerShowUnproved = "model-checker-show-unproved"; static string const g_strModelCheckerSolvers = "model-checker-solvers"; static string const g_strModelCheckerTargets = "model-checker-targets"; @@ -801,6 +802,13 @@ General Information)").c_str(), po::value()->value_name("all,bmc,chc,none")->default_value("none"), "Select model checker engine." ) + ( + g_strModelCheckerInvariants.c_str(), + po::value()->value_name("default,all,contract,reentrancy")->default_value("default"), + "Select whether to report inferred contract inductive invariants." + " Multiple types of invariants can be selected at the same time, separated by a comma and no spaces." + " By default no invariants are reported." + ) ( g_strModelCheckerShowUnproved.c_str(), "Show all unproved targets separately." @@ -1253,6 +1261,18 @@ bool CommandLineParser::processArgs() m_options.modelChecker.settings.engine = *engine; } + if (m_args.count(g_strModelCheckerInvariants)) + { + string invsStr = m_args[g_strModelCheckerInvariants].as(); + optional invs = ModelCheckerInvariants::fromString(invsStr); + if (!invs) + { + serr() << "Invalid option for --" << g_strModelCheckerInvariants << ": " << invsStr << endl; + return false; + } + m_options.modelChecker.settings.invariants = *invs; + } + if (m_args.count(g_strModelCheckerShowUnproved)) m_options.modelChecker.settings.showUnproved = true; @@ -1288,6 +1308,7 @@ bool CommandLineParser::processArgs() m_args.count(g_strModelCheckerContracts) || m_args.count(g_strModelCheckerDivModNoSlacks) || m_args.count(g_strModelCheckerEngine) || + m_args.count(g_strModelCheckerInvariants) || m_args.count(g_strModelCheckerShowUnproved) || m_args.count(g_strModelCheckerSolvers) || m_args.count(g_strModelCheckerTargets) || From 37215ffcfdb0889bffd1cde4b2bbb472394484d8 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:51:55 +0200 Subject: [PATCH 0026/1748] Add SMTCheckerTest isoltest option to ignore invariants --- libsolidity/formal/ModelCheckerSettings.h | 1 + test/libsolidity/SMTCheckerTest.cpp | 10 ++++++++++ test/libsolidity/SMTCheckerTest.h | 2 ++ 3 files changed, 13 insertions(+) diff --git a/libsolidity/formal/ModelCheckerSettings.h b/libsolidity/formal/ModelCheckerSettings.h index 3d137044a8..e3e93fcf40 100644 --- a/libsolidity/formal/ModelCheckerSettings.h +++ b/libsolidity/formal/ModelCheckerSettings.h @@ -95,6 +95,7 @@ struct ModelCheckerInvariants static ModelCheckerInvariants Default() { return *fromString("default"); } /// Adds all targets, including underflow and overflow. static ModelCheckerInvariants All() { return *fromString("all"); } + static ModelCheckerInvariants None() { return {{}}; } static std::optional fromString(std::string const& _invs); diff --git a/test/libsolidity/SMTCheckerTest.cpp b/test/libsolidity/SMTCheckerTest.cpp index 5606b0bfe3..3b6b8e1b80 100644 --- a/test/libsolidity/SMTCheckerTest.cpp +++ b/test/libsolidity/SMTCheckerTest.cpp @@ -19,6 +19,8 @@ #include #include +#include + using namespace std; using namespace solidity; using namespace solidity::langutil; @@ -67,6 +69,14 @@ SMTCheckerTest::SMTCheckerTest(string const& _filename): SyntaxTest(_filename, E else BOOST_THROW_EXCEPTION(runtime_error("Invalid SMT counterexample choice.")); + auto const& ignoreInv = m_reader.stringSetting("SMTIgnoreInv", "no"); + if (ignoreInv == "no") + m_modelCheckerSettings.invariants = ModelCheckerInvariants::All(); + else if (ignoreInv == "yes") + m_modelCheckerSettings.invariants = ModelCheckerInvariants::None(); + else + BOOST_THROW_EXCEPTION(runtime_error("Invalid SMT invariant choice.")); + auto const& ignoreOSSetting = m_reader.stringSetting("SMTIgnoreOS", "none"); for (string const& os: ignoreOSSetting | ranges::views::split(',') | ranges::to>()) { diff --git a/test/libsolidity/SMTCheckerTest.h b/test/libsolidity/SMTCheckerTest.h index 9cc4e57519..54d23c74fb 100644 --- a/test/libsolidity/SMTCheckerTest.h +++ b/test/libsolidity/SMTCheckerTest.h @@ -49,6 +49,8 @@ class SMTCheckerTest: public SyntaxTest Set in m_modelCheckerSettings. SMTIgnoreCex: `yes`, `no`, where the default is `no`. Set in m_ignoreCex. + SMTIgnoreInv: `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`. From a104443ac1a3f811c83157d7b1dc296c787e7ae2 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:52:16 +0200 Subject: [PATCH 0027/1748] Adjust errors script to also look for infos --- scripts/error_codes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 9290211a28..fe9c73b04b 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -125,7 +125,7 @@ def find_files(top_dir, sub_dirs, extensions): def find_ids_in_test_file(file_name): source = read_file(file_name) - pattern = r"^// (.*Error|Warning) \d\d\d\d:" + pattern = r"^// (.*Error|Warning|Info) \d\d\d\d:" return {m.group(0)[-5:-1] for m in re.finditer(pattern, source, flags=re.MULTILINE)} From 2cbd496576ec790d9a1fec89d140c385d60c6009 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:52:44 +0200 Subject: [PATCH 0028/1748] Adjust ModelCheckerSettings in tools tests --- test/solc/CommandLineParser.cpp | 4 ++++ test/tools/fuzzer_common.cpp | 1 + 2 files changed, 5 insertions(+) diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 3b2998ce12..663bf022c6 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -149,6 +149,7 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) "--model-checker-contracts=contract1.yul:A,contract2.yul:B", "--model-checker-div-mod-no-slacks", "--model-checker-engine=bmc", + "--model-checker-invariants=contract,reentrancy", "--model-checker-show-unproved", "--model-checker-solvers=z3,smtlib2", "--model-checker-targets=underflow,divByZero", @@ -212,6 +213,7 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) {{{"contract1.yul", {"A"}}, {"contract2.yul", {"B"}}}}, true, {true, false}, + {{InvariantType::Contract, InvariantType::Reentrancy}}, true, {false, true, true}, {{VerificationTargetType::Underflow, VerificationTargetType::DivByZero}}, @@ -285,6 +287,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) "contract2.yul:B", "--model-checker-div-mod-no-slacks", // Ignored in assembly mode "--model-checker-engine=bmc", // Ignored in assembly mode + "--model-checker-invariants=contract,reentrancy", // Ignored in assembly mode "--model-checker-show-unproved", // Ignored in assembly mode "--model-checker-solvers=z3,smtlib2", // Ignored in assembly mode "--model-checker-targets=" // Ignored in assembly mode @@ -375,6 +378,7 @@ BOOST_AUTO_TEST_CASE(standard_json_mode_options) "contract2.yul:B", "--model-checker-div-mod-no-slacks", // Ignored in Standard JSON mode "--model-checker-engine=bmc", // Ignored in Standard JSON mode + "--model-checker-invariants=contract,reentrancy", // Ignored in Standard JSON mode "--model-checker-show-unproved", // Ignored in Standard JSON mode "--model-checker-solvers=z3,smtlib2", // Ignored in Standard JSON mode "--model-checker-targets=" // Ignored in Standard JSON mode diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index 332b9fc04d..82066bf527 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -106,6 +106,7 @@ void FuzzerUtil::testCompiler( frontend::ModelCheckerContracts::Default(), /*divModWithSlacks*/true, frontend::ModelCheckerEngine::All(), + frontend::ModelCheckerInvariants::All(), /*showUnproved=*/false, smtutil::SMTSolverChoice::All(), frontend::ModelCheckerTargets::Default(), From 38b0cf7f9cbb29761c0cbc8d5f197daeeb094047 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:53:03 +0200 Subject: [PATCH 0029/1748] SMTChecker tests --- .../array_members/array_push_string_literal.sol | 3 ++- .../length_1d_assignment_2d_storage_to_storage.sol | 2 ++ .../array_members/length_1d_copy_2d_storage_to_memory.sol | 1 + .../array_members/length_1d_mapping_array_1.sol | 1 + .../smtCheckerTests/array_members/length_1d_struct_array_1.sol | 1 + .../array_members/length_1d_struct_array_2d_1.sol | 1 + .../smtCheckerTests/array_members/length_function_call.sol | 1 + .../array_members/length_same_after_assignment.sol | 1 + .../array_members/length_same_after_assignment_2.sol | 1 + .../array_members/length_same_after_assignment_2_fail.sol | 1 + .../array_members/length_same_after_assignment_3.sol | 1 + .../array_members/length_same_after_assignment_3_fail.sol | 2 ++ .../smtCheckerTests/array_members/push_as_lhs_1d.sol | 2 +- .../smtCheckerTests/array_members/push_as_lhs_and_rhs_1d.sol | 3 ++- .../smtCheckerTests/array_members/push_overflow_1_safe.sol | 1 + .../push_overflow_1_safe_no_overflow_assumption.sol | 1 + .../push_overflow_2_safe_no_overflow_assumption.sol | 2 ++ .../smtCheckerTests/array_members/push_push_no_args_2_fail.sol | 1 + .../array_members/push_storage_ref_unsafe_aliasing.sol | 1 + .../smtCheckerTests/blockchain_state/balance_non_zero_2.sol | 1 + .../smtCheckerTests/blockchain_state/balance_receive.sol | 1 + .../smtCheckerTests/blockchain_state/balance_receive_2.sol | 1 + .../smtCheckerTests/blockchain_state/balance_receive_4.sol | 3 ++- .../smtCheckerTests/blockchain_state/balance_receive_5.sol | 1 + .../smtCheckerTests/blockchain_state/balance_receive_calls.sol | 2 ++ .../blockchain_state/balance_receive_ext_calls.sol | 1 + .../blockchain_state/balance_receive_ext_calls_2.sol | 1 + .../blockchain_state/balance_receive_ext_calls_mutex.sol | 1 + .../smtCheckerTests/blockchain_state/balance_spend.sol | 1 + .../smtCheckerTests/blockchain_state/free_function_1.sol | 2 ++ .../smtCheckerTests/blockchain_state/free_function_2.sol | 1 + .../smtCheckerTests/blockchain_state/library_internal_1.sol | 2 ++ .../smtCheckerTests/blockchain_state/library_internal_2.sol | 1 + .../smtCheckerTests/blockchain_state/this_does_not_change.sol | 2 ++ .../blockchain_state/this_does_not_change_external_call.sol | 2 ++ .../blockchain_state/this_does_not_change_internal_call.sol | 1 + .../control_flow/branches_inside_modifiers_1.sol | 1 + .../control_flow/branches_inside_modifiers_2.sol | 1 + .../control_flow/branches_inside_modifiers_3.sol | 1 + .../control_flow/branches_inside_modifiers_4.sol | 1 + .../branches_with_return/branches_in_modifiers.sol | 1 + .../branches_with_return/branches_in_modifiers_2.sol | 2 +- .../control_flow/branches_with_return/triple_nested_if.sol | 1 + .../crypto_functions_same_input_over_state_same_output.sol | 1 + test/libsolidity/smtCheckerTests/external_calls/call_mutex.sol | 1 + .../smtCheckerTests/external_calls/call_reentrancy_view.sol | 2 ++ test/libsolidity/smtCheckerTests/external_calls/call_safe.sol | 1 + test/libsolidity/smtCheckerTests/external_calls/external.sol | 1 + .../external_calls/external_call_from_constructor_2.sol | 1 + .../smtCheckerTests/external_calls/external_hash.sol | 1 + .../external_calls/external_hash_known_code_pure.sol | 1 + .../external_calls/external_hash_known_code_state.sol | 1 + .../external_hash_known_code_state_reentrancy_2.sol | 2 ++ .../external_hash_known_code_state_reentrancy_3.sol | 1 + .../smtCheckerTests/external_calls/external_reentrancy_3.sol | 2 ++ .../external_calls/external_reentrancy_crypto.sol | 1 + .../smtCheckerTests/external_calls/external_safe.sol | 1 + test/libsolidity/smtCheckerTests/external_calls/mutex.sol | 1 + .../smtCheckerTests/external_calls/staticcall_mutex.sol | 1 + .../smtCheckerTests/external_calls/staticcall_mutex_2.sol | 1 + .../external_calls/staticcall_reentrancy_view.sol | 1 + .../smtCheckerTests/functions/functions_external_1.sol | 2 ++ .../smtCheckerTests/functions/functions_external_2.sol | 2 ++ .../smtCheckerTests/functions/functions_external_3.sol | 1 + .../functions/functions_identifier_nested_tuple_1.sol | 1 + .../smtCheckerTests/functions/functions_recursive_indirect.sol | 1 + test/libsolidity/smtCheckerTests/functions/getters/array_1.sol | 1 + test/libsolidity/smtCheckerTests/functions/getters/array_2.sol | 1 + .../smtCheckerTests/functions/getters/array_of_structs_1.sol | 1 + .../functions/getters/nested_arrays_mappings_1.sol | 1 + .../functions/getters/nested_arrays_mappings_10.sol | 1 + .../functions/getters/nested_arrays_mappings_2.sol | 1 + .../functions/getters/nested_arrays_mappings_3.sol | 1 + .../functions/getters/nested_arrays_mappings_4.sol | 1 + .../functions/getters/nested_arrays_mappings_5.sol | 1 + .../functions/getters/nested_arrays_mappings_6.sol | 1 + .../functions/getters/nested_arrays_mappings_7.sol | 1 + .../functions/getters/nested_arrays_mappings_8.sol | 1 + .../functions/getters/nested_arrays_mappings_9.sol | 1 + .../smtCheckerTests/functions/getters/static_array.sol | 1 + .../libsolidity/smtCheckerTests/functions/getters/struct_3.sol | 1 + .../functions/internal_call_with_assertion_1.sol | 2 ++ .../functions/internal_call_with_assertion_1_fail.sol | 1 + .../functions/internal_multiple_calls_with_assertion_1.sol | 1 + .../internal_multiple_calls_with_assertion_1_fail.sol | 1 + .../smtCheckerTests/functions/super_function_assert.sol | 1 + test/libsolidity/smtCheckerTests/functions/this_state.sol | 1 + .../smtCheckerTests/functions/virtual_function_assert.sol | 1 + .../functions/virtual_function_called_by_constructor.sol | 2 ++ .../inheritance/base_contract_assertion_fail_1.sol | 1 + .../inheritance/base_contract_assertion_fail_9.sol | 1 + .../inheritance/constructor_uses_function_base.sol | 1 + .../smtCheckerTests/inheritance/diamond_super_3.sol | 1 + .../inheritance/implicit_constructor_hierarchy.sol | 1 + .../inheritance/implicit_only_constructor_hierarchy.sol | 1 + .../libsolidity/smtCheckerTests/invariants/state_machine_1.sol | 1 + .../modifier_inside_branch_assignment_multi_branches.sol | 1 + .../smtCheckerTests/modifiers/modifier_overflow.sol | 1 + .../smtCheckerTests/modifiers/modifier_overriding_4.sol | 1 + .../smtCheckerTests/modifiers/modifier_two_invocations_2.sol | 1 + .../modifiers/modifier_virtual_static_call_2.sol | 1 + .../natspec/safe_assert_false_positive_pure.sol | 1 + .../operators/assignment_contract_member_variable.sol | 1 + .../operators/assignment_contract_member_variable_array.sol | 1 + .../operators/assignment_contract_member_variable_array_3.sol | 1 + .../operators/assignment_module_contract_member_variable.sol | 1 + .../smtCheckerTests/operators/compound_bitwise_or_uint_2.sol | 1 + .../smtCheckerTests/operators/conditional_assignment_6.sol | 2 ++ test/libsolidity/smtCheckerTests/operators/delete_array_2d.sol | 1 + .../smtCheckerTests/operators/delete_array_index.sol | 1 + .../smtCheckerTests/operators/delete_array_index_2d.sol | 1 + test/libsolidity/smtCheckerTests/operators/delete_function.sol | 1 + .../smtCheckerTests/operators/index_access_side_effect.sol | 1 + .../smtCheckerTests/operators/unary_add_array_push_2.sol | 1 + test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol | 3 +++ test/libsolidity/smtCheckerTests/out_of_bounds/array_2.sol | 1 + .../smtCheckerTests/overflow/signed_guard_sub_overflow.sol | 1 + test/libsolidity/smtCheckerTests/special/msg_value_3.sol | 1 + .../smtCheckerTests/special/msg_vars_chc_internal.sol | 3 ++- test/libsolidity/smtCheckerTests/try_catch/try_4.sol | 1 + test/libsolidity/smtCheckerTests/try_catch/try_5.sol | 1 + .../smtCheckerTests/try_catch/try_multiple_returned_values.sol | 1 + .../smtCheckerTests/try_catch/try_public_var_mapping.sol | 2 ++ test/libsolidity/smtCheckerTests/typecast/address_literal.sol | 1 + test/libsolidity/smtCheckerTests/types/address_call.sol | 2 ++ test/libsolidity/smtCheckerTests/types/address_staticcall.sol | 1 + .../smtCheckerTests/types/array_aliasing_memory_3.sol | 1 + test/libsolidity/smtCheckerTests/types/array_branch_3d.sol | 1 + test/libsolidity/smtCheckerTests/types/array_branches_3d.sol | 1 + .../smtCheckerTests/types/array_branches_3d_show_unproved.sol | 1 + .../smtCheckerTests/types/array_mapping_aliasing_2.sol | 1 + .../smtCheckerTests/types/array_static_mapping_aliasing_1.sol | 1 + .../smtCheckerTests/types/array_static_mapping_aliasing_2.sol | 1 + .../libsolidity/smtCheckerTests/types/enum_explicit_values.sol | 1 + .../libsolidity/smtCheckerTests/types/fixed_bytes_access_1.sol | 1 + .../libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol | 3 +++ test/libsolidity/smtCheckerTests/types/mapping_4.sol | 1 + .../smtCheckerTests/types/static_array_length_5.sol | 1 + .../smtCheckerTests/types/struct/struct_state_constructor.sol | 1 + .../libsolidity/smtCheckerTests/types/tuple_extra_parens_7.sol | 1 + test/libsolidity/smtCheckerTests/userTypes/mapping_1.sol | 3 +++ 141 files changed, 169 insertions(+), 6 deletions(-) diff --git a/test/libsolidity/smtCheckerTests/array_members/array_push_string_literal.sol b/test/libsolidity/smtCheckerTests/array_members/array_push_string_literal.sol index 55b2160c44..5ed512278b 100644 --- a/test/libsolidity/smtCheckerTests/array_members/array_push_string_literal.sol +++ b/test/libsolidity/smtCheckerTests/array_members/array_push_string_literal.sol @@ -13,6 +13,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- -// Warning 6328: (139-161): CHC: Assertion violation happens here. +// Warning 6328: (139-161): CHC: Assertion violation happens here.\nCounterexample:\ndata = [0x62]\n\nTransaction trace:\nC.constructor()\nState: data = []\nC.g() // Warning 6328: (263-290): CHC: Assertion violation happens here.\nCounterexample:\ndata = [0x01]\n\nTransaction trace:\nC.constructor()\nState: data = []\nC.g() diff --git a/test/libsolidity/smtCheckerTests/array_members/length_1d_assignment_2d_storage_to_storage.sol b/test/libsolidity/smtCheckerTests/array_members/length_1d_assignment_2d_storage_to_storage.sol index 4796e3a817..2940383991 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_1d_assignment_2d_storage_to_storage.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_1d_assignment_2d_storage_to_storage.sol @@ -16,4 +16,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- +// Info 1180: Contract invariant(s) for :C:\n!(arr.length <= 0)\n!(arr2.length <= 0)\n(((arr.length + ((- 1) * arr2.length)) <= 0) && ((arr2.length + ((- 1) * arr.length)) <= 0))\n(((arr2[0].length + ((- 1) * arr[0].length)) >= 0) && ((arr2[0].length + ((- 1) * arr[0].length)) <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/array_members/length_1d_copy_2d_storage_to_memory.sol b/test/libsolidity/smtCheckerTests/array_members/length_1d_copy_2d_storage_to_memory.sol index 5ad65991a2..468f34257a 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_1d_copy_2d_storage_to_memory.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_1d_copy_2d_storage_to_memory.sol @@ -17,3 +17,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(arr.length <= 1)\n diff --git a/test/libsolidity/smtCheckerTests/array_members/length_1d_mapping_array_1.sol b/test/libsolidity/smtCheckerTests/array_members/length_1d_mapping_array_1.sol index c6e695f243..48e0f73bf2 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_1d_mapping_array_1.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_1d_mapping_array_1.sol @@ -7,3 +7,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(true && (map[1].length <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_1.sol b/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_1.sol index 3ab2187411..833caa24f8 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_1.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_1.sol @@ -11,3 +11,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(((s1.arr.length + ((- 1) * s2.arr.length)) >= 0) && ((s1.arr.length + ((- 1) * s2.arr.length)) <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_2d_1.sol b/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_2d_1.sol index cd9b6690d5..71571d9448 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_2d_1.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_2d_1.sol @@ -21,3 +21,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(s1.arr.length <= 0)\n!(s2.arr.length <= 0)\n(((s2.arr[0].length + ((- 1) * s1.arr[0].length)) <= 0) && ((s1.arr[0].length + ((- 1) * s2.arr[0].length)) <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/array_members/length_function_call.sol b/test/libsolidity/smtCheckerTests/array_members/length_function_call.sol index a51c7aa7d6..c96d53047c 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_function_call.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_function_call.sol @@ -9,3 +9,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(arr.length <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment.sol b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment.sol index 5756c7affc..4f1cf701b4 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment.sol @@ -15,3 +15,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(arr.length <= 2)\n diff --git a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_2.sol b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_2.sol index 525c704e11..66dad84128 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_2.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_2.sol @@ -23,3 +23,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(arr.length <= 2)\n!(arr.length <= 3)\n!(arr[2].length <= 3)\n diff --git a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_2_fail.sol b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_2_fail.sol index 086224a11d..0023906fef 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_2_fail.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_2_fail.sol @@ -27,3 +27,4 @@ contract C { // Warning 6328: (291-317): CHC: Assertion violation happens here. // Warning 6328: (321-347): CHC: Assertion violation happens here. // Warning 6328: (351-374): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n!(arr.length <= 2)\n!(arr.length <= 3)\n!(arr[2].length <= 3)\n diff --git a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3.sol b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3.sol index 78a020e056..caafcbd397 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3.sol @@ -28,3 +28,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(arr.length <= 7)\n!(arr.length <= 8)\n((arr[5].length <= 0) && (arr[8].length <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3_fail.sol b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3_fail.sol index f4d5c889c6..062b668c38 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3_fail.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3_fail.sol @@ -25,8 +25,10 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (319-345): CHC: Assertion violation happens here.\nCounterexample:\narr = [[], [], [], [], [], [], [], [], []]\nx = 0\ny = 0\nz = 9\nt = 0\n\nTransaction trace:\nC.constructor()\nState: arr = [[], [], [], [], [], [], [], [], []]\nC.f() // Warning 6328: (349-375): CHC: Assertion violation happens here.\nCounterexample:\narr = [[], [], [], [], [], [], [], [], []]\nx = 0\ny = 0\nz = 9\nt = 0\n\nTransaction trace:\nC.constructor()\nState: arr = [[], [], [], [], [], [], [], [], []]\nC.f() // Warning 6328: (379-402): CHC: Assertion violation happens here.\nCounterexample:\narr = [[], [], [], [], [], [], [], [], []]\nx = 0\ny = 0\nz = 9\nt = 0\n\nTransaction trace:\nC.constructor()\nState: arr = [[], [], [], [], [], [], [], [], []]\nC.f() // Warning 6328: (406-432): CHC: Assertion violation happens here.\nCounterexample:\narr = [[], [], [], [], [], [], [], [], []]\nx = 0\ny = 0\nz = 9\nt = 0\n\nTransaction trace:\nC.constructor()\nState: arr = [[], [], [], [], [], [], [], [], []]\nC.f() +// Info 1180: Contract invariant(s) for :C:\n!(arr.length <= 3)\n!(arr.length <= 5)\n!(arr.length <= 7)\n!(arr.length <= 8)\n diff --git a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol index 5920a4e747..30f194eb7c 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol @@ -18,4 +18,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (199-229): CHC: Assertion violation happens here.\nCounterexample:\nb = [1]\n\nTransaction trace:\nC.constructor()\nState: b = []\nC.g() +// Warning 6328: (199-229): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_1d.sol b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_1d.sol index 6b23ac1d4a..ad3ba78234 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_1d.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_1d.sol @@ -12,5 +12,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- -// Warning 6328: (204-230): CHC: Assertion violation happens here. +// Warning 6328: (204-230): CHC: Assertion violation happens here.\nCounterexample:\nb = [0, 0]\nlength = 2\n\nTransaction trace:\nC.constructor()\nState: b = []\nC.f() diff --git a/test/libsolidity/smtCheckerTests/array_members/push_overflow_1_safe.sol b/test/libsolidity/smtCheckerTests/array_members/push_overflow_1_safe.sol index 0a440e7a41..930736ce8d 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_overflow_1_safe.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_overflow_1_safe.sol @@ -8,4 +8,5 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreInv: yes // ---- diff --git a/test/libsolidity/smtCheckerTests/array_members/push_overflow_1_safe_no_overflow_assumption.sol b/test/libsolidity/smtCheckerTests/array_members/push_overflow_1_safe_no_overflow_assumption.sol index 6992ca1e40..9cc3f2e375 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_overflow_1_safe_no_overflow_assumption.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_overflow_1_safe_no_overflow_assumption.sol @@ -9,3 +9,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(!((x[x.length] := 23)[0] >= 43) && !((x[x.length] := 23)[0] <= 41))\n diff --git a/test/libsolidity/smtCheckerTests/array_members/push_overflow_2_safe_no_overflow_assumption.sol b/test/libsolidity/smtCheckerTests/array_members/push_overflow_2_safe_no_overflow_assumption.sol index 1b241745a1..60b11c91a6 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_overflow_2_safe_no_overflow_assumption.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_overflow_2_safe_no_overflow_assumption.sol @@ -11,4 +11,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- +// Info 1180: Contract invariant(s) for :C:\n(x.length >= 0)\n diff --git a/test/libsolidity/smtCheckerTests/array_members/push_push_no_args_2_fail.sol b/test/libsolidity/smtCheckerTests/array_members/push_push_no_args_2_fail.sol index c29c34f626..dcda253ce4 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_push_no_args_2_fail.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_push_no_args_2_fail.sol @@ -10,6 +10,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (90-116): CHC: Assertion violation happens here.\nCounterexample:\narray2d = [[[0]]]\nlast = 0\n\nTransaction trace:\nC.constructor()\nState: array2d = []\nC.l() // Warning 6328: (170-186): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/array_members/push_storage_ref_unsafe_aliasing.sol b/test/libsolidity/smtCheckerTests/array_members/push_storage_ref_unsafe_aliasing.sol index 43eebddcfb..87b9d92bf3 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_storage_ref_unsafe_aliasing.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_storage_ref_unsafe_aliasing.sol @@ -12,6 +12,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6368: (188-192): CHC: Out of bounds access happens here.\nCounterexample:\na = []\nb = [32]\n\nTransaction trace:\nC.constructor()\nState: a = []\nC.f() // Warning 6368: (188-195): CHC: Out of bounds access happens here.\nCounterexample:\n\nb = [32]\n\nTransaction trace:\nC.constructor()\nState: a = []\nC.f() diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_non_zero_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_non_zero_2.sol index 100f11066e..f88eab0bf4 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_non_zero_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_non_zero_2.sol @@ -11,3 +11,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (153-188): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor(){ msg.value: 101 }\nC.f() +// Info 1180: Contract invariant(s) for :C:\n!((:var 0).balances[address(this)] <= 100)\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive.sol index ea5947d01e..fc4719cefd 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive.sol @@ -16,3 +16,4 @@ contract C { // ---- // Warning 6328: (132-188): CHC: Assertion violation happens here. // Warning 6328: (269-324): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n((prevBalance + ((- 1) * (:var 1).balances[address(this)])) <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_2.sol index c561179ec1..c4714e2e3b 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_2.sol @@ -17,3 +17,4 @@ contract C { // ---- // Warning 4984: (266-272): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\nx = 115792089237316195423570985008687907853269984665640564039457584007913129639926, once = true\n\nTransaction trace:\nC.constructor(){ msg.value: 28100 }\nState: x = 115792089237316195423570985008687907853269984665640564039457584007913129639926, once = false\nC.f(){ msg.value: 8 } // Warning 6328: (235-273): CHC: Assertion violation happens here.\nCounterexample:\nx = 0, once = true\n\nTransaction trace:\nC.constructor(){ msg.value: 0 }\nState: x = 0, once = false\nC.f(){ msg.value: 8 } +// Info 1180: Contract invariant(s) for :C:\nonce\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol index 183e60d95e..e8f750d07a 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol @@ -15,7 +15,8 @@ contract C { // Warning 4984: (82-85): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. // Warning 4984: (154-160): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. // Warning 4984: (212-218): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 6328: (180-219): CHC: Assertion violation happens here.\nCounterexample:\nc = 1\n\nTransaction trace:\nC.constructor()\nState: c = 0\nC.f(){ msg.value: 11 }\nState: c = 1\nC.inv() +// Warning 6328: (180-219): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n(((11 * c) + ((- 1) * (:var 1).balances[address(this)])) <= 0)\n // Warning 2661: (82-85): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. // Warning 2661: (154-160): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. // Warning 2661: (212-218): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_5.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_5.sol index e703c65c38..1885a60c81 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_5.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_5.sol @@ -12,3 +12,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (122-158): CHC: Assertion violation happens here.\nCounterexample:\nsum = 0\n\nTransaction trace:\nC.constructor()\nState: sum = 0\nC.inv() +// Info 1180: Contract invariant(s) for :C:\n((sum + ((- 1) * (:var 1).balances[address(this)])) <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_calls.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_calls.sol index 3bc5699978..263a90b08d 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_calls.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_calls.sol @@ -20,7 +20,9 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (173-208): CHC: Assertion violation happens here.\nCounterexample:\nonce = true\n\nTransaction trace:\nC.constructor()\nState: once = false\nC.f(){ msg.value: 10 } // Warning 6328: (321-356): CHC: Assertion violation happens here.\nCounterexample:\nonce = true\n\nTransaction trace:\nC.constructor()\nState: once = false\nC.f(){ msg.value: 10 }\n C.g() -- internal call // Warning 6328: (469-504): CHC: Assertion violation happens here.\nCounterexample:\nonce = true\n\nTransaction trace:\nC.constructor()\nState: once = false\nC.f(){ msg.value: 10 }\n C.g() -- internal call\n C.h() -- internal call +// Info 1180: Contract invariant(s) for :C:\n((:var 1).balances[address(this)] >= 0)\nonce\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol index 6144056a89..e46dfda34b 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol @@ -15,4 +15,5 @@ contract C { // ---- // Warning 1218: (131-165): CHC: Error trying to invoke SMT solver. // Warning 6328: (131-165): CHC: Assertion violation might happen here. +// Info 1180: Reentrancy property(ies) for :C:\n(!( >= 2) && (((:var 0).balances[address(this)] + ((- 1) * (:var 1).balances[address(this)])) >= 0))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this).balance == x)\n = 2 -> Assertion failed at assert(address(this).balance >= x)\n // Warning 4661: (131-165): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_2.sol index e0da57fb29..28c4734bd4 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_2.sol @@ -12,3 +12,4 @@ contract C { // ---- // Warning 9302: (82-93): Return value of low-level calls not used. // Warning 6328: (97-131): CHC: Assertion violation happens here. +// Info 1180: Reentrancy property(ies) for :C:\n((((:var 1).balances[address(this)] + ((- 1) * (:var 0).balances[address(this)])) <= 0) && !( >= 2))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this).balance == x)\n = 2 -> Assertion failed at assert(address(this).balance >= x)\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_mutex.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_mutex.sol index 59c1234295..559f67e193 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_mutex.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_mutex.sol @@ -22,3 +22,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (277-310): CHC: Assertion violation happens here. +// Info 1180: Reentrancy property(ies) for :C:\n((!lock || (((:var 3).balances[address(this)] + ((- 1) * (:var 1).balances[address(this)])) <= 0)) && !( = 1) && (lock' || !lock) && (!lock || (((:var 3).balances[address(this)] + ((- 1) * (:var 1).balances[address(this)])) >= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this).balance == x)\n = 2 -> Assertion failed at assert(address(this).balance < x)\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol index 72755cc35d..1e4ec7a32a 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol @@ -19,4 +19,5 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (280-314): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n((!(c <= 1) || !((:var 1).balances[address(this)] <= 91)) && !((:var 1).balances[address(this)] <= 82) && (!(c <= 0) || !((:var 1).balances[address(this)] <= 100)))\n // Warning 1236: (175-190): BMC: Insufficient funds happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/free_function_1.sol b/test/libsolidity/smtCheckerTests/blockchain_state/free_function_1.sol index 9b40afa2e2..260d3c942b 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/free_function_1.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/free_function_1.sol @@ -13,3 +13,5 @@ contract C { } // ==== // SMTEngine: all +// ---- +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/free_function_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/free_function_2.sol index 6c3d120260..50081bc5aa 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/free_function_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/free_function_2.sol @@ -20,4 +20,5 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (258-274): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\n // Warning 1236: (33-46): BMC: Insufficient funds happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_1.sol b/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_1.sol index 4f7497625f..9df3aa27a0 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_1.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_1.sol @@ -16,3 +16,5 @@ contract C { } // ==== // SMTEngine: all +// ---- +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_2.sol index 8fca1916fb..f32652da97 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/library_internal_2.sol @@ -23,4 +23,5 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (315-331): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\n // Warning 1236: (87-100): BMC: Insufficient funds happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change.sol b/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change.sol index 7e233950c2..0b66b27919 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change.sol @@ -9,4 +9,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- +// Info 1180: Contract invariant(s) for :C:\n(((address(this) + ((- 1) * t)) <= 0) && ((address(this) + ((- 1) * t)) >= 0))\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_external_call.sol b/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_external_call.sol index f3abd33c9d..0b5136dcab 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_external_call.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_external_call.sol @@ -16,4 +16,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- +// Info 1180: Contract invariant(s) for :C:\n(((address(this) + ((- 1) * t)) <= 0) && ((address(this) + ((- 1) * t)) >= 0))\nReentrancy property(ies) for :C:\n((!( >= 2) || !((t + ((- 1) * address(this))) = 0)) && (!((t + ((- 1) * address(this))) <= 0) || ((t' + ((- 1) * address(this))) <= 0)) && (!((t + ((- 1) * address(this))) >= 0) || ((address(this) + ((- 1) * t')) <= 0)))\n((( <= 0) || !((t + ((- 1) * address(this))) = 0)) && (!((t + ((- 1) * address(this))) <= 0) || ((t' + ((- 1) * address(this))) <= 0)) && (!((t + ((- 1) * address(this))) >= 0) || ((address(this) + ((- 1) * t')) <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this) == t)\n = 2 -> Assertion failed at assert(a == t)\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_internal_call.sol b/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_internal_call.sol index 3c7b1214ed..0ffe434693 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_internal_call.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_internal_call.sol @@ -14,3 +14,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(((t + ((- 1) * address(this))) >= 0) && ((t + ((- 1) * address(this))) <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_1.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_1.sol index 0976371681..21f1f5c7f2 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_1.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_1.sol @@ -23,3 +23,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (327-341): CHC: Assertion violation happens here.\nCounterexample:\nx = 7\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.g()\n C.f() -- internal call +// Info 1180: Contract invariant(s) for :C:\n((x = 0) || (x = 7))\n diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_2.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_2.sol index 458c78081b..bf1da4275e 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_2.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_2.sol @@ -23,3 +23,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (333-347): CHC: Assertion violation happens here.\nCounterexample:\nx = 3\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.g()\n C.f() -- internal call +// Info 1180: Contract invariant(s) for :C:\n((x = 0) || (x = 3))\n diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_3.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_3.sol index b8323501cd..ace158bb9f 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_3.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_3.sol @@ -23,3 +23,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (326-340): CHC: Assertion violation happens here.\nCounterexample:\nx = 3\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.g()\n C.f() -- internal call +// Info 1180: Contract invariant(s) for :C:\n((x = 0) || (x = 3))\n diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_4.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_4.sol index 81f8b3d7cb..44910fa62c 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_4.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_4.sol @@ -24,3 +24,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (333-347): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n((x = 0) || (x = 7))\n diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers.sol index aa8199cd0a..32d647762d 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers.sol @@ -24,3 +24,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (70-84): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.test() +// Info 1180: Contract invariant(s) for :C:\n(x = 0)\n diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol index 4241fa9e29..9765fc1f91 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol @@ -44,5 +44,5 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (255-269): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.test()\n C.reset_if_overflow() -- internal call -// Warning 6328: (502-519): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\noldx = 1\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.set(1)\nState: x = 1\nC.test()\n C.reset_if_overflow() -- internal call +// Warning 6328: (502-519): CHC: Assertion violation happens here. // Warning 6328: (615-629): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.set(10)\nState: x = 10\nC.test()\n C.reset_if_overflow() -- internal call diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/triple_nested_if.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/triple_nested_if.sol index 9ca87a4b07..09ee2b2b24 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/triple_nested_if.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/triple_nested_if.sol @@ -18,3 +18,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n((c <= 0) && (a <= 0) && (b <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_over_state_same_output.sol b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_over_state_same_output.sol index aae296695a..228f9d5809 100644 --- a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_over_state_same_output.sol +++ b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_over_state_same_output.sol @@ -37,3 +37,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(((erc + ((- 1) * ecrecover(tuple_constructor(h, v, r, s)))) <= 0) && ((erc + ((- 1) * ecrecover(tuple_constructor(h, v, r, s)))) >= 0))\n(((kec + ((- 1) * keccak256(data))) >= 0) && ((kec + ((- 1) * keccak256(data))) <= 0))\n(((rip + ((- 1) * ripemd160(data))) <= 0) && ((rip + ((- 1) * ripemd160(data))) >= 0))\n(((sha + ((- 1) * sha256(data))) <= 0) && ((sha + ((- 1) * sha256(data))) >= 0))\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_mutex.sol b/test/libsolidity/smtCheckerTests/external_calls/call_mutex.sol index 4352a7e95b..a310939246 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_mutex.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_mutex.sol @@ -23,3 +23,4 @@ contract C { // SMTEngine: all // ---- // Warning 9302: (218-234): Return value of low-level calls not used. +// Info 1180: Reentrancy property(ies) for :C:\n((!lock || ((x' + ((- 1) * x)) = 0)) && ( <= 0) && (lock' || !lock))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(y == x)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_reentrancy_view.sol b/test/libsolidity/smtCheckerTests/external_calls/call_reentrancy_view.sol index 69c2e29532..f0f844fff3 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_reentrancy_view.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_reentrancy_view.sol @@ -10,7 +10,9 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 2519: (106-112): This declaration shadows an existing declaration. // Warning 2072: (106-112): Unused local variable. // Warning 2072: (114-131): Unused local variable. +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n((!(x <= 0) || (x' <= 0)) && (( <= 0) || !(x <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol b/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol index 33791dd0d5..09d3a25922 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol @@ -10,3 +10,4 @@ contract C { // ---- // Warning 2072: (57-63): Unused local variable. // Warning 2072: (65-82): Unused local variable. +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n((!(x <= 0) || (x' <= 0)) && (( <= 0) || !(x <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/external.sol b/test/libsolidity/smtCheckerTests/external_calls/external.sol index 8dd0f404a2..659329e0b8 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external.sol @@ -18,3 +18,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (167-181): CHC: Assertion violation happens here. +// Info 1180: Reentrancy property(ies) for :C:\n!( = 1)\n = 0 -> no errors\n = 1 -> Overflow at ++x\n = 3 -> Assertion failed at assert(x < 10)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_2.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_2.sol index cfd56271ba..3fbdd8511b 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_2.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_2.sol @@ -14,3 +14,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (87-101): CHC: Assertion violation happens here.\nCounterexample:\nz = 2\n_x = 0\n = 0\n\nTransaction trace:\nC.constructor()\nState: z = 2\nC.g(0) +// Info 1180: Contract invariant(s) for :C:\n(!(z >= 3) && !(z <= 1))\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash.sol index 3464874c85..8f5b162a0d 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash.sol @@ -28,3 +28,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (390-412): CHC: Assertion violation happens here. +// Info 1180: Reentrancy property(ies) for :C:\n!( = 1)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(prevOwner == owner)\n = 3 -> Assertion failed at assert(sig_1 == sig_2)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_pure.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_pure.sol index e1273a2997..2e837478d8 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_pure.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_pure.sol @@ -30,3 +30,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (398-420): CHC: Assertion violation happens here. +// Info 1180: Reentrancy property(ies) for :C:\n!( = 1)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(prevOwner == owner)\n = 3 -> Assertion failed at assert(sig_1 == sig_2)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state.sol index ecf7ff5adf..317400e1d1 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state.sol @@ -36,3 +36,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (495-532): CHC: Assertion violation happens here. +// Info 1180: Reentrancy property(ies) for :C:\n(((owner + ((- 1) * owner')) >= 0) && !( = 1) && ((owner + ((- 1) * owner')) <= 0))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(prevOwner == owner)\n = 3 -> Assertion failed at assert(owner == address(0) || y != z)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_2.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_2.sol index a90e87cb3d..be9f698e15 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_2.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_2.sol @@ -38,6 +38,8 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreInv: yes +// SMTIgnoreOS: macos // ---- // Warning 2018: (33-88): Function state mutability can be restricted to view // Warning 6328: (367-381): CHC: Assertion violation happens here. 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 83ab8873b3..e5259c6c44 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 @@ -41,3 +41,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n((insidef || (z <= 0)) && (y <= 0))\nReentrancy property(ies) for :C:\n((!insidef || !( >= 2)) && (!(y <= 0) || (y' <= 0)) && (insidef' || !insidef))\n((!insidef || !( >= 3)) && (insidef' || !insidef))\n = 0 -> no errors\n = 2 -> Assertion failed at assert(z == y)\n = 3 -> Assertion failed at assert(prevOwner == owner)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_3.sol b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_3.sol index ff2cd7c857..590133a784 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_3.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_3.sol @@ -28,5 +28,7 @@ contract C is A { // ==== // SMTEngine: all // SMTIgnoreCex: yes +// SMTIgnoreInv: yes +// SMTIgnoreOS: macos // ---- // Warning 6328: (154-168): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol index 98f6d80be7..627f797630 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol @@ -28,4 +28,5 @@ contract C { // ---- // Warning 1218: (302-333): CHC: Error trying to invoke SMT solver. // Warning 6328: (302-333): CHC: Assertion violation might happen here. +// Info 1180: Contract invariant(s) for :C:\n(((kec + ((- 1) * keccak256(data))) >= 0) && ((kec + ((- 1) * keccak256(data))) <= 0))\nReentrancy property(ies) for :C:\n((!((kec + ((- 1) * keccak256(data))) >= 0) || ((kec' + ((- 1) * keccak256(data'))) >= 0)) && (!((kec + ((- 1) * keccak256(data))) <= 0) || ((kec' + ((- 1) * keccak256(data'))) <= 0)))\n((!( = 1) || !((kec + ((- 1) * keccak256(data))) = 0)) && (!((kec + ((- 1) * keccak256(data))) <= 0) || ((kec' + ((- 1) * keccak256(data'))) <= 0)) && (!((kec + ((- 1) * keccak256(data))) >= 0) || ((kec' + ((- 1) * keccak256(data'))) >= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(_kec == kec)\n = 2 -> Assertion failed at assert(kec == keccak256(_data))\n // Warning 4661: (302-333): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol b/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol index a2b0f1363c..5921189b7a 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_safe.sol @@ -17,3 +17,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(x >= 11)\nReentrancy property(ies) for :C:\n!( = 1)\n((!(x <= 10) || !( >= 3)) && (!(x <= 10) || !(x' >= 11)))\n = 0 -> no errors\n = 1 -> Overflow at ++x\n = 3 -> Assertion failed at assert(x < 11)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/mutex.sol b/test/libsolidity/smtCheckerTests/external_calls/mutex.sol index 977115ec01..79b5ac1538 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/mutex.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/mutex.sol @@ -26,4 +26,5 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreInv: yes // ---- diff --git a/test/libsolidity/smtCheckerTests/external_calls/staticcall_mutex.sol b/test/libsolidity/smtCheckerTests/external_calls/staticcall_mutex.sol index 30f4392c54..b7fa571972 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/staticcall_mutex.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/staticcall_mutex.sol @@ -23,3 +23,4 @@ contract C { // SMTEngine: all // ---- // Warning 9302: (218-240): Return value of low-level calls not used. +// Info 1180: Reentrancy property(ies) for :C:\n((!lock || ( <= 0)) && (lock' || !lock))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(y == x)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/staticcall_mutex_2.sol b/test/libsolidity/smtCheckerTests/external_calls/staticcall_mutex_2.sol index bccf18caf2..f87cf5f743 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/staticcall_mutex_2.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/staticcall_mutex_2.sol @@ -24,3 +24,4 @@ contract C { // ---- // Warning 9302: (212-234): Return value of low-level calls not used. // Warning 2018: (164-271): Function state mutability can be restricted to view +// Info 1180: Reentrancy property(ies) for :C:\n( <= 0)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(y == x)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/staticcall_reentrancy_view.sol b/test/libsolidity/smtCheckerTests/external_calls/staticcall_reentrancy_view.sol index 96a73cb5d3..ee9e571890 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/staticcall_reentrancy_view.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/staticcall_reentrancy_view.sol @@ -15,3 +15,4 @@ contract C { // Warning 2072: (106-112): Unused local variable. // Warning 2072: (114-131): Unused local variable. // Warning 2018: (72-188): Function state mutability can be restricted to view +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n diff --git a/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol b/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol index 6887c00db6..ace2d56f29 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol @@ -16,4 +16,6 @@ contract C } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n!( = 1)\n((!(x <= 0) || !( >= 2)) && (!(x <= 0) || (x' <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == y)\n = 2 -> Assertion failed at assert(x == y)\n diff --git a/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol b/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol index bc2fa2dc35..5efcb2da1b 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol @@ -22,5 +22,7 @@ contract C // ==== // SMTEngine: all // SMTIgnoreCex: yes +// SMTIgnoreOS: macos // ---- // Warning 6328: (234-253): CHC: Assertion violation happens here. +// Info 1180: Reentrancy property(ies) for :C:\n!( = 1)\n((!((map[1] + ((- 1) * map[0])) <= 0) || ((map'[1] + ((- 1) * map'[0])) <= 0)) && !( = 2) && (!((map[1] + ((- 1) * map[0])) >= 0) || ((map'[0] + ((- 1) * map'[1])) <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(map[0] == map[1])\n = 2 -> Assertion failed at assert(map[0] == map[1])\n = 3 -> Assertion failed at assert(map[0] == 0)\n diff --git a/test/libsolidity/smtCheckerTests/functions/functions_external_3.sol b/test/libsolidity/smtCheckerTests/functions/functions_external_3.sol index 93273800e8..d83970977b 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_external_3.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_external_3.sol @@ -18,3 +18,4 @@ contract C // ==== // SMTEngine: all // ---- +// Info 1180: Reentrancy property(ies) for :C:\n!( >= 2)\n( <= 0)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(map[0] == map[1])\n = 2 -> Assertion failed at assert(map[0] == map[1])\n diff --git a/test/libsolidity/smtCheckerTests/functions/functions_identifier_nested_tuple_1.sol b/test/libsolidity/smtCheckerTests/functions/functions_identifier_nested_tuple_1.sol index 2afe4b1ffa..fb3228aca9 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_identifier_nested_tuple_1.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_identifier_nested_tuple_1.sol @@ -14,3 +14,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n((x = 0) || (x = 1))\n diff --git a/test/libsolidity/smtCheckerTests/functions/functions_recursive_indirect.sol b/test/libsolidity/smtCheckerTests/functions/functions_recursive_indirect.sol index 8b4218b454..530b469009 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_recursive_indirect.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_recursive_indirect.sol @@ -23,3 +23,4 @@ contract C // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(a <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/array_1.sol b/test/libsolidity/smtCheckerTests/functions/getters/array_1.sol index b3f6cad02d..421c4fd4f0 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/array_1.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/array_1.sol @@ -16,3 +16,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (187-201): CHC: Assertion violation happens here.\nCounterexample:\na = [0, 0, 0, 0]\ny = 0\n\nTransaction trace:\nC.constructor()\nState: a = [0, 0, 0, 0]\nC.f() +// Info 1180: Contract invariant(s) for :C:\n!(a.length <= 2)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/array_2.sol b/test/libsolidity/smtCheckerTests/functions/getters/array_2.sol index d4e1dc1473..ebc7877f0a 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/array_2.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/array_2.sol @@ -20,3 +20,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (242-256): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n!(a.length <= 2)\n!(a[2].length <= 3)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/array_of_structs_1.sol b/test/libsolidity/smtCheckerTests/functions/getters/array_of_structs_1.sol index 5a9b13aff6..5038294ed5 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/array_of_structs_1.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/array_of_structs_1.sol @@ -15,3 +15,4 @@ contract D { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :D:\n(items[1][2][3].y <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_1.sol b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_1.sol index b90bc412a8..30907bd673 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_1.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_1.sol @@ -17,3 +17,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (210-224): CHC: Assertion violation happens here.\nCounterexample:\n\ny = 42\n\nTransaction trace:\nC.constructor()\nC.f() +// Info 1180: Contract invariant(s) for :C:\n!(m[0].length <= 1)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_10.sol b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_10.sol index 7fa0381b62..56032d9d5f 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_10.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_10.sol @@ -20,3 +20,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (256-270): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n!(m.length <= 0)\n!(m[0][1].length <= 2)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_2.sol b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_2.sol index f1afc6e805..c3a3d660de 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_2.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_2.sol @@ -21,3 +21,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (274-288): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n!(m[0].length <= 1)\n!(m[0][1].length <= 2)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_3.sol b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_3.sol index 97cc03919c..0083f92d89 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_3.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_3.sol @@ -24,3 +24,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(m[0].length <= 1)\n!(m[0][1].length <= 2)\n!(m[0][1][2].length <= 3)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_4.sol b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_4.sol index 4aca89ef77..43047758ef 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_4.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_4.sol @@ -19,3 +19,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (260-274): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n!(m[0][1].length <= 2)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_5.sol b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_5.sol index ce22da600c..2e8abe5dcd 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_5.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_5.sol @@ -23,3 +23,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (354-368): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n!(m[0][1].length <= 2)\n!(m[0][1][2].length <= 3)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_6.sol b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_6.sol index 3ad4d94ae8..d7964552d6 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_6.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_6.sol @@ -19,3 +19,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(m[0][1][2].length <= 3)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_7.sol b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_7.sol index 5c5af070ea..fc4c9efcf9 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_7.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_7.sol @@ -16,3 +16,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (192-206): CHC: Assertion violation happens here.\nCounterexample:\n\ny = 42\n\nTransaction trace:\nC.constructor()\nC.f() +// Info 1180: Contract invariant(s) for :C:\n!(m.length <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_8.sol b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_8.sol index 1a0f9a7991..0b2b6fadf7 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_8.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_8.sol @@ -18,3 +18,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (232-246): CHC: Assertion violation happens here.\nCounterexample:\n\ny = 42\n\nTransaction trace:\nC.constructor()\nC.f() +// Info 1180: Contract invariant(s) for :C:\n!(m.length <= 0)\n!(m[0].length <= 1)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_9.sol b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_9.sol index 8df8edad48..be6bc23834 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_9.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_9.sol @@ -16,3 +16,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (218-232): CHC: Assertion violation happens here.\nCounterexample:\n\ny = 42\n\nTransaction trace:\nC.constructor()\nC.f() +// Info 1180: Contract invariant(s) for :C:\n!(m.length <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/static_array.sol b/test/libsolidity/smtCheckerTests/functions/getters/static_array.sol index d77ab04e3c..d66545e437 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/static_array.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/static_array.sol @@ -13,3 +13,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (162-184): CHC: Assertion violation happens here.\nCounterexample:\nx = [42, 1]\n\nTransaction trace:\nC.constructor()\nState: x = [42, 1]\nC.f() +// Info 1180: Contract invariant(s) for :C:\n!(x.length <= 1)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/struct_3.sol b/test/libsolidity/smtCheckerTests/functions/getters/struct_3.sol index ddeaa655b2..ea433b7863 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/struct_3.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/struct_3.sol @@ -22,3 +22,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (307-326): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n!(m.b.length <= 2)\n diff --git a/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_1.sol b/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_1.sol index 3083327005..c3c231ede5 100644 --- a/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_1.sol +++ b/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_1.sol @@ -19,5 +19,7 @@ contract C{ } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 5667: (37-43): Unused function parameter. Remove or comment out the variable name to silence this warning. +// Info 1180: Contract invariant(s) for :C:\n!(x >= 2)\n(!(x <= 0) && !(x >= 2))\n(!(x >= 2) && !(x <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_1_fail.sol b/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_1_fail.sol index 1fe537aade..d067795ac8 100644 --- a/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_1_fail.sol +++ b/test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_1_fail.sol @@ -26,3 +26,4 @@ contract C{ // Warning 6328: (137-151): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\n\nTransaction trace:\nC.constructor(0)\nState: x = 1\nC.f()\n C.g() -- internal call // Warning 6328: (187-201): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nC.constructor(0)\nState: x = 1\nC.f()\n C.g() -- internal call // Warning 6328: (212-226): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\n\nTransaction trace:\nC.constructor(0)\nState: x = 1\nC.f()\n C.g() -- internal call +// Info 1180: Contract invariant(s) for :C:\n!(x >= 2)\n diff --git a/test/libsolidity/smtCheckerTests/functions/internal_multiple_calls_with_assertion_1.sol b/test/libsolidity/smtCheckerTests/functions/internal_multiple_calls_with_assertion_1.sol index 3f17744fb6..4bca2544e1 100644 --- a/test/libsolidity/smtCheckerTests/functions/internal_multiple_calls_with_assertion_1.sol +++ b/test/libsolidity/smtCheckerTests/functions/internal_multiple_calls_with_assertion_1.sol @@ -21,3 +21,4 @@ contract C{ // SMTEngine: all // ---- // Warning 5667: (37-43): Unused function parameter. Remove or comment out the variable name to silence this warning. +// Info 1180: Contract invariant(s) for :C:\n!(x <= 0)\n!(x >= 2)\n(!(x <= 0) && !(x >= 2))\n diff --git a/test/libsolidity/smtCheckerTests/functions/internal_multiple_calls_with_assertion_1_fail.sol b/test/libsolidity/smtCheckerTests/functions/internal_multiple_calls_with_assertion_1_fail.sol index f03e1b4ebc..c0f524e106 100644 --- a/test/libsolidity/smtCheckerTests/functions/internal_multiple_calls_with_assertion_1_fail.sol +++ b/test/libsolidity/smtCheckerTests/functions/internal_multiple_calls_with_assertion_1_fail.sol @@ -24,3 +24,4 @@ contract C{ // Warning 6328: (49-63): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\ny = 0\n\nTransaction trace:\nC.constructor(0) // Warning 6328: (105-119): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\n\nTransaction trace:\nC.constructor(0)\nState: x = 1\nC.f() // Warning 6328: (151-165): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\n\nTransaction trace:\nC.constructor(0)\nState: x = 1\nC.f()\n C.g() -- internal call\n C.g() -- internal call +// Info 1180: Contract invariant(s) for :C:\n!(x <= 0)\n!(x >= 2)\n diff --git a/test/libsolidity/smtCheckerTests/functions/super_function_assert.sol b/test/libsolidity/smtCheckerTests/functions/super_function_assert.sol index 58d541a8a4..85e97661ce 100644 --- a/test/libsolidity/smtCheckerTests/functions/super_function_assert.sol +++ b/test/libsolidity/smtCheckerTests/functions/super_function_assert.sol @@ -31,3 +31,4 @@ contract D is C { // ---- // Warning 6328: (205-219): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nC.constructor()\nState: x = 0\nA.proxy()\n C.f() -- internal call\n A.f() -- internal call // Warning 6328: (328-342): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nD.constructor()\nState: x = 0\nA.proxy()\n D.f() -- internal call\n C.f() -- internal call\n A.f() -- internal call +// Info 1180: Contract invariant(s) for :A:\n((x = 0) || (x = 2))\nContract invariant(s) for :D:\n((x = 0) || (x = 2))\n diff --git a/test/libsolidity/smtCheckerTests/functions/this_state.sol b/test/libsolidity/smtCheckerTests/functions/this_state.sol index 4d69e4815e..126add6406 100644 --- a/test/libsolidity/smtCheckerTests/functions/this_state.sol +++ b/test/libsolidity/smtCheckerTests/functions/this_state.sol @@ -13,3 +13,4 @@ contract C // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n((x = 0) || (x = 2))\n diff --git a/test/libsolidity/smtCheckerTests/functions/virtual_function_assert.sol b/test/libsolidity/smtCheckerTests/functions/virtual_function_assert.sol index 4c4a8b2461..4c5e381310 100644 --- a/test/libsolidity/smtCheckerTests/functions/virtual_function_assert.sol +++ b/test/libsolidity/smtCheckerTests/functions/virtual_function_assert.sol @@ -20,3 +20,4 @@ contract C is A { // SMTEngine: all // ---- // Warning 6328: (227-241): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nA.proxy()\n C.f() -- internal call +// Info 1180: Contract invariant(s) for :A:\n((x >= 0) && (x <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/functions/virtual_function_called_by_constructor.sol b/test/libsolidity/smtCheckerTests/functions/virtual_function_called_by_constructor.sol index 17f3daa794..0117f9b49d 100644 --- a/test/libsolidity/smtCheckerTests/functions/virtual_function_called_by_constructor.sol +++ b/test/libsolidity/smtCheckerTests/functions/virtual_function_called_by_constructor.sol @@ -23,6 +23,8 @@ contract C is A { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (199-214): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nA.constructor()\nState: x = 2\nA.i() // Warning 6328: (387-401): CHC: Assertion violation happens here.\nCounterexample:\nx = 10\n\nTransaction trace:\nC.constructor()\nState: x = 10\nC.i() +// Info 1180: Contract invariant(s) for :A:\n(!(x <= 1) && !(x >= 3))\nContract invariant(s) for :C:\n(!(x >= 11) && !(x <= 9))\n 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 c86ea3e596..1f05d11765 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol @@ -16,3 +16,4 @@ contract C is B { // SMTEngine: all // ---- // Warning 6328: (52-66): CHC: Assertion violation happens here.\nCounterexample:\ny = 0, x = 1\n\nTransaction trace:\nC.constructor()\nState: y = 0, x = 0\nC.g()\n B.f() -- internal call\nState: y = 0, x = 1\nB.f() +// Info 1180: Contract invariant(s) for :B:\n(x <= 0)\n 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 f97bae5cd1..a87a8eeb68 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_9.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_9.sol @@ -30,3 +30,4 @@ 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 1180: Contract invariant(s) for :A:\n(x = 0)\n diff --git a/test/libsolidity/smtCheckerTests/inheritance/constructor_uses_function_base.sol b/test/libsolidity/smtCheckerTests/inheritance/constructor_uses_function_base.sol index e70d372304..0a4599a3d1 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/constructor_uses_function_base.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/constructor_uses_function_base.sol @@ -18,3 +18,4 @@ contract C is B { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(!(y <= 41) && !(y >= 43))\n diff --git a/test/libsolidity/smtCheckerTests/inheritance/diamond_super_3.sol b/test/libsolidity/smtCheckerTests/inheritance/diamond_super_3.sol index 959e53d45f..b8487e3212 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/diamond_super_3.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/diamond_super_3.sol @@ -33,3 +33,4 @@ contract E is C,D { // SMTEngine: all // ---- // 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 1180: Contract invariant(s) for :C:\n((x = 0) || (x = 111))\nContract invariant(s) for :D:\n((x = 0) || (x = 101))\nContract invariant(s) for :E:\n((x = 0) || (x = 111))\nContract invariant(s) for :B:\n((x = 0) || (x = 101))\n diff --git a/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol b/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol index 1490276912..59d0423028 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol @@ -16,3 +16,4 @@ contract C is B { // SMTEngine: all // SMTSolvers: z3 // ---- +// Info 1180: Contract invariant(s) for :C:\n(!(x <= 1) && !(x >= 3))\n diff --git a/test/libsolidity/smtCheckerTests/inheritance/implicit_only_constructor_hierarchy.sol b/test/libsolidity/smtCheckerTests/inheritance/implicit_only_constructor_hierarchy.sol index 2b1de17cb2..653bb23b70 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/implicit_only_constructor_hierarchy.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/implicit_only_constructor_hierarchy.sol @@ -20,3 +20,4 @@ contract C is B { // SMTEngine: all // SMTSolvers: z3 // ---- +// Info 1180: Contract invariant(s) for :A:\n(x <= 0)\nContract invariant(s) for :C:\n(x <= 0)\nContract invariant(s) for :B:\n(x <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/invariants/state_machine_1.sol b/test/libsolidity/smtCheckerTests/invariants/state_machine_1.sol index beafa4af09..91b96f78c0 100644 --- a/test/libsolidity/smtCheckerTests/invariants/state_machine_1.sol +++ b/test/libsolidity/smtCheckerTests/invariants/state_machine_1.sol @@ -32,3 +32,4 @@ contract C { // SMTEngine: all // SMTSolvers: z3 // ---- +// Info 1180: Contract invariant(s) for :C:\n!(x >= 7)\n diff --git a/test/libsolidity/smtCheckerTests/modifiers/modifier_inside_branch_assignment_multi_branches.sol b/test/libsolidity/smtCheckerTests/modifiers/modifier_inside_branch_assignment_multi_branches.sol index 9a578cf897..d3467d0b89 100644 --- a/test/libsolidity/smtCheckerTests/modifiers/modifier_inside_branch_assignment_multi_branches.sol +++ b/test/libsolidity/smtCheckerTests/modifiers/modifier_inside_branch_assignment_multi_branches.sol @@ -35,3 +35,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (540-554): CHC: Assertion violation happens here.\nCounterexample:\nx = 1, owner = 0x0\ny = 1\n\nTransaction trace:\nC.constructor()\nState: x = 0, owner = 0x0\nC.g(1){ msg.sender: 0x0 } +// Info 1180: Contract invariant(s) for :C:\n(owner <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/modifiers/modifier_overflow.sol b/test/libsolidity/smtCheckerTests/modifiers/modifier_overflow.sol index 13a83ee551..25141b8bf3 100644 --- a/test/libsolidity/smtCheckerTests/modifiers/modifier_overflow.sol +++ b/test/libsolidity/smtCheckerTests/modifiers/modifier_overflow.sol @@ -15,3 +15,4 @@ contract C // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_4.sol b/test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_4.sol index 7da8d0f6a5..39be35cb6d 100644 --- a/test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_4.sol +++ b/test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_4.sol @@ -39,3 +39,4 @@ contract D is B,C { // 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 1180: Contract invariant(s) for :C:\n((x = 0) || (x = 2))\nContract invariant(s) for :D:\n((x = 0) || (x = 3))\nContract invariant(s) for :B:\n((x = 0) || (x = 1))\n diff --git a/test/libsolidity/smtCheckerTests/modifiers/modifier_two_invocations_2.sol b/test/libsolidity/smtCheckerTests/modifiers/modifier_two_invocations_2.sol index 0a63ed321d..5641e2812b 100644 --- a/test/libsolidity/smtCheckerTests/modifiers/modifier_two_invocations_2.sol +++ b/test/libsolidity/smtCheckerTests/modifiers/modifier_two_invocations_2.sol @@ -17,3 +17,4 @@ contract C // SMTEngine: all // ---- // Warning 6328: (76-90): CHC: Assertion violation happens here.\nCounterexample:\nx = 3\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f() +// Info 1180: Contract invariant(s) for :C:\n(x = 3)\n diff --git a/test/libsolidity/smtCheckerTests/modifiers/modifier_virtual_static_call_2.sol b/test/libsolidity/smtCheckerTests/modifiers/modifier_virtual_static_call_2.sol index 4bd8f328f7..43d41f755b 100644 --- a/test/libsolidity/smtCheckerTests/modifiers/modifier_virtual_static_call_2.sol +++ b/test/libsolidity/smtCheckerTests/modifiers/modifier_virtual_static_call_2.sol @@ -21,3 +21,4 @@ contract C is A { // SMTEngine: all // ---- // Warning 6328: (83-98): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\n = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.f() +// Info 1180: Contract invariant(s) for :C:\n((x >= 0) && (x <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/natspec/safe_assert_false_positive_pure.sol b/test/libsolidity/smtCheckerTests/natspec/safe_assert_false_positive_pure.sol index 11fcbf6f67..ed160d95c2 100644 --- a/test/libsolidity/smtCheckerTests/natspec/safe_assert_false_positive_pure.sol +++ b/test/libsolidity/smtCheckerTests/natspec/safe_assert_false_positive_pure.sol @@ -28,3 +28,4 @@ contract C { // Warning 2018: (33-335): Function state mutability can be restricted to view // Warning 2018: (457-524): Function state mutability can be restricted to pure // Warning 6328: (135-150): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\n(y <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable.sol b/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable.sol index 3331b57de9..284f9bcbd5 100644 --- a/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable.sol +++ b/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable.sol @@ -29,3 +29,4 @@ contract A { // SMTIgnoreCex: yes // ---- // Warning 6328: (392-408): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :A:\n(((x = (- 2)) && (y = (- 2))) || ((x = 0) && (y = 0)))\n(((x = 0) && (y = 0)) || ((x = (- 2)) && (y = (- 2))))\n diff --git a/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array.sol b/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array.sol index 3df77d2fb0..292eab85d2 100644 --- a/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array.sol +++ b/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array.sol @@ -13,3 +13,4 @@ contract A { // SMTEngine: all // ---- // Warning 6328: (124-146): CHC: Assertion violation happens here.\nCounterexample:\na = []\n\nTransaction trace:\nA.constructor()\nState: a = []\nA.f() +// Info 1180: Contract invariant(s) for :A:\n(a.length <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array_3.sol b/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array_3.sol index fac19a6ff6..7a925d1341 100644 --- a/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array_3.sol +++ b/test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array_3.sol @@ -30,3 +30,4 @@ contract A { // Warning 6328: (311-328): CHC: Assertion violation happens here.\nCounterexample:\na = [0, 0]\nb = [0, 0]\n\nTransaction trace:\nA.constructor()\nState: a = [1]\nA.f() // Warning 6368: (422-426): CHC: Out of bounds access happens here.\nCounterexample:\na = [0, 0]\nu = []\nb = [0, 0]\n\nTransaction trace:\nA.constructor()\nState: a = [1]\nA.f() // Warning 6328: (415-432): CHC: Assertion violation happens here.\nCounterexample:\na = [0, 0]\nb = [0, 0]\n\nTransaction trace:\nA.constructor()\nState: a = [1]\nA.f() +// Info 1180: Contract invariant(s) for :A:\n!(a.length <= 0)\n 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 d1387ee8ef..e4b7646861 100644 --- a/test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol +++ b/test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol @@ -30,3 +30,4 @@ contract A { // ---- // Warning 6328: (AASource:159-178): CHC: Assertion violation happens here.\nCounterexample:\nx = (- 1), y = (- 2)\n\nTransaction trace:\nA.constructor()\nState: x = 0, y = 0\nA.a()\nState: x = (- 2), y = (- 2)\nA.a() // Warning 6328: (AASource:370-386): CHC: Assertion violation happens here.\nCounterexample:\nx = 8, y = (- 2)\n\nTransaction trace:\nA.constructor()\nState: x = 0, y = 0\nA.a() +// Info 1180: Contract invariant(s) for AASource:A:\n(((x = (- 2)) && (y = (- 2))) || ((x = 0) && (y = 0)))\n(((x = 0) && (y = 0)) || ((x = (- 2)) && (y = (- 2))))\n diff --git a/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_2.sol b/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_2.sol index 17c812aec7..9b27a277b9 100644 --- a/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_2.sol +++ b/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_2.sol @@ -19,3 +19,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(s.x.length <= 2)\n diff --git a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol index 58afa2413d..e37d3f84c2 100644 --- a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol +++ b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol @@ -22,5 +22,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 2072: (255-261): Unused local variable. +// Info 1180: Reentrancy property(ies) for :C:\n((!(x <= 2) || !(x' >= 3)) && ( <= 0) && (!(x' <= 0) || !(x >= 2)))\n((!(x' <= 0) || ((x' + ((- 1) * x)) = 0)) && ( <= 0) && (!(x' >= 3) || ((x' + ((- 1) * x)) = 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 2 || x == 1)\n diff --git a/test/libsolidity/smtCheckerTests/operators/delete_array_2d.sol b/test/libsolidity/smtCheckerTests/operators/delete_array_2d.sol index bda1c07f28..32f2526cc6 100644 --- a/test/libsolidity/smtCheckerTests/operators/delete_array_2d.sol +++ b/test/libsolidity/smtCheckerTests/operators/delete_array_2d.sol @@ -17,3 +17,4 @@ contract C // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(true && !(a.length <= 2))\n(true && !(a[2].length <= 3))\n diff --git a/test/libsolidity/smtCheckerTests/operators/delete_array_index.sol b/test/libsolidity/smtCheckerTests/operators/delete_array_index.sol index ea9c4f55ae..4f90011158 100644 --- a/test/libsolidity/smtCheckerTests/operators/delete_array_index.sol +++ b/test/libsolidity/smtCheckerTests/operators/delete_array_index.sol @@ -20,4 +20,5 @@ contract C // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(a.length <= 2)\n // Warning 6838: (154-155): BMC: Condition is always false. diff --git a/test/libsolidity/smtCheckerTests/operators/delete_array_index_2d.sol b/test/libsolidity/smtCheckerTests/operators/delete_array_index_2d.sol index b0ec97d98d..80a692429d 100644 --- a/test/libsolidity/smtCheckerTests/operators/delete_array_index_2d.sol +++ b/test/libsolidity/smtCheckerTests/operators/delete_array_index_2d.sol @@ -27,4 +27,5 @@ contract C // SMTIgnoreCex: yes // ---- // Warning 6328: (315-335): CHC: Assertion violation might happen here. +// Info 1180: Contract invariant(s) for :C:\n!(a.length <= 1)\n // Warning 4661: (315-335): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/operators/delete_function.sol b/test/libsolidity/smtCheckerTests/operators/delete_function.sol index f40a02c935..63dad1ab0b 100644 --- a/test/libsolidity/smtCheckerTests/operators/delete_function.sol +++ b/test/libsolidity/smtCheckerTests/operators/delete_function.sol @@ -28,4 +28,5 @@ contract C // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(a.length <= 2)\n // Warning 6838: (262-263): BMC: Condition is always true. diff --git a/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol b/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol index 6de2c9c616..ae526775f9 100644 --- a/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol +++ b/test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol @@ -23,4 +23,5 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (335-354): CHC: Assertion violation might happen here. +// Info 1180: Contract invariant(s) for :C:\n!(a.length <= 2)\n!(a.length <= 3)\n // Warning 4661: (335-354): BMC: Assertion violation happens here. 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 0c2fdba6f9..b1cef5e40b 100644 --- a/test/libsolidity/smtCheckerTests/operators/unary_add_array_push_2.sol +++ b/test/libsolidity/smtCheckerTests/operators/unary_add_array_push_2.sol @@ -18,3 +18,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(data.length <= 1)\n!(data[1].d.length <= 3)\n diff --git a/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol b/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol index 8997abbe63..ee57f069d4 100644 --- a/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol +++ b/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol @@ -18,7 +18,10 @@ contract C { } // ==== // SMTEngine: all +// 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.\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() // 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/out_of_bounds/array_2.sol b/test/libsolidity/smtCheckerTests/out_of_bounds/array_2.sol index 6adc6273c8..d331abef7b 100644 --- a/test/libsolidity/smtCheckerTests/out_of_bounds/array_2.sol +++ b/test/libsolidity/smtCheckerTests/out_of_bounds/array_2.sol @@ -21,3 +21,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n((l + ((- 1) * a.length)) <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/overflow/signed_guard_sub_overflow.sol b/test/libsolidity/smtCheckerTests/overflow/signed_guard_sub_overflow.sol index afaeb54483..b28b6598c7 100644 --- a/test/libsolidity/smtCheckerTests/overflow/signed_guard_sub_overflow.sol +++ b/test/libsolidity/smtCheckerTests/overflow/signed_guard_sub_overflow.sol @@ -6,5 +6,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 4984: (96-101): CHC: Overflow (resulting value larger than 0x80 * 2**248 - 1) happens here.\nCounterexample:\n\nx = 0\ny = (- 57896044618658097711785492504343953926634992332820282019728792003956564819968)\n = 0\n\nTransaction trace:\nC.constructor()\nC.f(0, (- 57896044618658097711785492504343953926634992332820282019728792003956564819968)) diff --git a/test/libsolidity/smtCheckerTests/special/msg_value_3.sol b/test/libsolidity/smtCheckerTests/special/msg_value_3.sol index 8d35e17542..79302b1429 100644 --- a/test/libsolidity/smtCheckerTests/special/msg_value_3.sol +++ b/test/libsolidity/smtCheckerTests/special/msg_value_3.sol @@ -13,3 +13,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\nlock\n diff --git a/test/libsolidity/smtCheckerTests/special/msg_vars_chc_internal.sol b/test/libsolidity/smtCheckerTests/special/msg_vars_chc_internal.sol index b7984d21ef..475cc2291e 100644 --- a/test/libsolidity/smtCheckerTests/special/msg_vars_chc_internal.sol +++ b/test/libsolidity/smtCheckerTests/special/msg_vars_chc_internal.sol @@ -8,6 +8,7 @@ contract C { sender = msg.sender; sig = msg.sig; value = msg.value; + require(value == 42); g(); } @@ -28,4 +29,4 @@ contract C { // ==== // SMTEngine: chc // ---- -// Warning 6328: (621-644): CHC: Assertion violation happens here.\nCounterexample:\ndata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0\n\nTransaction trace:\nC.constructor()\nState: data = [], sender = 0x0, sig = 0x0, value = 0\nC.f(){ msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0 }\n C.g() -- internal call +// Warning 6328: (645-668): CHC: Assertion violation happens here.\nCounterexample:\ndata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 42\n\nTransaction trace:\nC.constructor()\nState: data = [], sender = 0x0, sig = 0x0, value = 0\nC.f(){ msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 42 }\n C.g() -- internal call diff --git a/test/libsolidity/smtCheckerTests/try_catch/try_4.sol b/test/libsolidity/smtCheckerTests/try_catch/try_4.sol index 6988906a27..0abf62df8e 100644 --- a/test/libsolidity/smtCheckerTests/try_catch/try_4.sol +++ b/test/libsolidity/smtCheckerTests/try_catch/try_4.sol @@ -28,4 +28,5 @@ contract C { // Warning 1218: (178-192): CHC: Error trying to invoke SMT solver. // Warning 6328: (178-192): CHC: Assertion violation might happen here. // Warning 6328: (318-332): CHC: Assertion violation happens here. +// Info 1180: Reentrancy property(ies) for :C:\n!( = 2)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n = 2 -> Assertion failed at assert(x == 0)\n = 3 -> Assertion failed at assert(x == 1)\n // Warning 4661: (178-192): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/try_catch/try_5.sol b/test/libsolidity/smtCheckerTests/try_catch/try_5.sol index 6c9b776c4e..236a26f1bd 100644 --- a/test/libsolidity/smtCheckerTests/try_catch/try_5.sol +++ b/test/libsolidity/smtCheckerTests/try_catch/try_5.sol @@ -26,3 +26,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (315-329): CHC: Assertion violation happens here.\nCounterexample:\nx = 0, d = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0, d = 0\nC.f() +// Info 1180: Reentrancy property(ies) for :C:\n!( = 2)\n((!(x' >= 100) || ((x' + ((- 1) * x)) = 0)) && !( = 1))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x < 100)\n = 2 -> Assertion failed at assert(x == 0)\n = 3 -> Assertion failed at assert(x == 1)\n diff --git a/test/libsolidity/smtCheckerTests/try_catch/try_multiple_returned_values.sol b/test/libsolidity/smtCheckerTests/try_catch/try_multiple_returned_values.sol index 80ebe0d933..abef4c76a4 100644 --- a/test/libsolidity/smtCheckerTests/try_catch/try_multiple_returned_values.sol +++ b/test/libsolidity/smtCheckerTests/try_catch/try_multiple_returned_values.sol @@ -25,3 +25,4 @@ contract C { // Warning 6328: (185-199): CHC: Assertion violation happens here.\nCounterexample:\nx = 0, d = 0\nx = 1\nc = false\n\nTransaction trace:\nC.constructor()\nState: x = 0, d = 0\nC.f()\n d.d() -- untrusted external call // Warning 6328: (273-283): CHC: Assertion violation happens here.\nCounterexample:\nx = 0, d = 0\nx = 1\nc = true\n\nTransaction trace:\nC.constructor()\nState: x = 0, d = 0\nC.f()\n d.d() -- untrusted external call // Warning 6328: (393-407): CHC: Assertion violation happens here.\nCounterexample:\nx = 0, d = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0, d = 0\nC.f() +// Info 1180: Reentrancy property(ies) for :C:\n!( = 3)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n = 2 -> Assertion failed at assert(!c)\n = 3 -> Assertion failed at assert(x == 0)\n = 4 -> Assertion failed at assert(x == 1)\n diff --git a/test/libsolidity/smtCheckerTests/try_catch/try_public_var_mapping.sol b/test/libsolidity/smtCheckerTests/try_catch/try_public_var_mapping.sol index 3048558e78..0854dedd17 100644 --- a/test/libsolidity/smtCheckerTests/try_catch/try_public_var_mapping.sol +++ b/test/libsolidity/smtCheckerTests/try_catch/try_public_var_mapping.sol @@ -19,5 +19,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (280-300): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.f() +// Info 1180: Contract invariant(s) for :C:\n!(m[0].length <= 1)\n(!(m[0][1] >= 43) && !(m[0][1] <= 41))\n diff --git a/test/libsolidity/smtCheckerTests/typecast/address_literal.sol b/test/libsolidity/smtCheckerTests/typecast/address_literal.sol index d56275fedc..40540bb511 100644 --- a/test/libsolidity/smtCheckerTests/typecast/address_literal.sol +++ b/test/libsolidity/smtCheckerTests/typecast/address_literal.sol @@ -23,3 +23,4 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (454-468): CHC: Assertion violation happens here.\nCounterexample:\nx = 0x0\na = 0x0\nb = 0x01\nc = 0x0\nd = 0x0\ne = 0x12345678\n\nTransaction trace:\nC.constructor()\nState: x = 0x0\nC.g() +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/types/address_call.sol b/test/libsolidity/smtCheckerTests/types/address_call.sol index 568ab91e1d..8ea3894827 100644 --- a/test/libsolidity/smtCheckerTests/types/address_call.sol +++ b/test/libsolidity/smtCheckerTests/types/address_call.sol @@ -19,6 +19,8 @@ contract C // EVMVersion: >spuriousDragon // SMTEngine: all // SMTIgnoreCex: yes +// SMTIgnoreInv: yes +// SMTIgnoreOS: macos // ---- // Warning 2072: (127-166): Unused local variable. // Warning 2072: (191-207): Unused local variable. diff --git a/test/libsolidity/smtCheckerTests/types/address_staticcall.sol b/test/libsolidity/smtCheckerTests/types/address_staticcall.sol index 40d867fa0d..11b862a10c 100644 --- a/test/libsolidity/smtCheckerTests/types/address_staticcall.sol +++ b/test/libsolidity/smtCheckerTests/types/address_staticcall.sol @@ -20,3 +20,4 @@ contract C // ---- // Warning 2072: (191-207): Unused local variable. // Warning 6328: (233-248): CHC: Assertion violation happens here. +// Info 1180: Reentrancy property(ies) for :C:\n!( >= 2)\n!( >= 3)\n!( >= 4)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(success)\n = 2 -> Assertion failed at assert(x == 0)\n = 3 -> Assertion failed at assert(map[0] == 0)\n = 4 -> Assertion failed at assert(localMap[0] == 0)\n diff --git a/test/libsolidity/smtCheckerTests/types/array_aliasing_memory_3.sol b/test/libsolidity/smtCheckerTests/types/array_aliasing_memory_3.sol index 36b851ff3e..7e89f1c9d0 100644 --- a/test/libsolidity/smtCheckerTests/types/array_aliasing_memory_3.sol +++ b/test/libsolidity/smtCheckerTests/types/array_aliasing_memory_3.sol @@ -28,3 +28,4 @@ contract C // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n!(array.length <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol b/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol index c13842daaf..fad9d2bbac 100644 --- a/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol +++ b/test/libsolidity/smtCheckerTests/types/array_branch_3d.sol @@ -23,3 +23,4 @@ contract C // 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.\nCounterexample:\nc = [[[0]]]\nb = false\n\nTransaction trace:\nC.constructor()\nState: c = [[[0]]]\nC.f(false) +// Info 1180: Contract invariant(s) for :C:\n!(c.length <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol b/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol index ebd28101d5..b2fd913278 100644 --- a/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol +++ b/test/libsolidity/smtCheckerTests/types/array_branches_3d.sol @@ -22,3 +22,4 @@ contract C // 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 1180: Contract invariant(s) for :C:\n!(c.length <= 0)\n 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 6ec629c9f6..689fc045d9 100644 --- a/test/libsolidity/smtCheckerTests/types/array_branches_3d_show_unproved.sol +++ b/test/libsolidity/smtCheckerTests/types/array_branches_3d_show_unproved.sol @@ -23,3 +23,4 @@ contract C // 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 1180: Contract invariant(s) for :C:\n!(c.length <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/types/array_mapping_aliasing_2.sol b/test/libsolidity/smtCheckerTests/types/array_mapping_aliasing_2.sol index 07e09a9e82..dd0d8e004e 100644 --- a/test/libsolidity/smtCheckerTests/types/array_mapping_aliasing_2.sol +++ b/test/libsolidity/smtCheckerTests/types/array_mapping_aliasing_2.sol @@ -43,3 +43,4 @@ contract C // 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. +// Info 1180: Contract invariant(s) for :C:\n!(severalMaps8.length <= 0)\n 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 cde229e4fa..f415cfd955 100644 --- a/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_1.sol +++ b/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_1.sol @@ -28,3 +28,4 @@ contract C // SMTIgnoreCex: yes // ---- // Warning 6328: (456-487): CHC: Assertion violation happens here. +// Info 1180: Contract invariant(s) for :C:\n!(severalMaps3d.length <= 1)\n!(severalMaps8.length <= 1)\n 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 8ebd7025d8..f9aa3a650d 100644 --- a/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_2.sol +++ b/test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_2.sol @@ -33,3 +33,4 @@ contract C // Warning 6328: (860-880): CHC: Assertion violation happens here. // Warning 6368: (936-952): CHC: Out of bounds access might happen here. // Warning 6368: (936-955): CHC: Out of bounds access might happen here. +// Info 1180: Contract invariant(s) for :C:\n!(severalMaps8.length <= 1)\n diff --git a/test/libsolidity/smtCheckerTests/types/enum_explicit_values.sol b/test/libsolidity/smtCheckerTests/types/enum_explicit_values.sol index fda74030ea..edc35f8029 100644 --- a/test/libsolidity/smtCheckerTests/types/enum_explicit_values.sol +++ b/test/libsolidity/smtCheckerTests/types/enum_explicit_values.sol @@ -11,3 +11,4 @@ contract C // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n((d = 0) || (d = 1))\n diff --git a/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_1.sol b/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_1.sol index 2aee190425..6a24c1e9c9 100644 --- a/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_1.sol +++ b/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_1.sol @@ -7,3 +7,4 @@ contract c { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :c:\n!(data2.length <= 5)\n diff --git a/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol b/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol index 941cfd2372..b55293231f 100644 --- a/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol +++ b/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol @@ -30,5 +30,8 @@ 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 1180: Contract invariant(s) for :C:\n!(a.length <= 4)\n diff --git a/test/libsolidity/smtCheckerTests/types/mapping_4.sol b/test/libsolidity/smtCheckerTests/types/mapping_4.sol index c5b0357401..ba6688cd5f 100644 --- a/test/libsolidity/smtCheckerTests/types/mapping_4.sol +++ b/test/libsolidity/smtCheckerTests/types/mapping_4.sol @@ -10,3 +10,4 @@ contract C // SMTEngine: all // SMTSolvers: z3 // ---- +// Info 1180: Contract invariant(s) for :C:\n!map[true]\n diff --git a/test/libsolidity/smtCheckerTests/types/static_array_length_5.sol b/test/libsolidity/smtCheckerTests/types/static_array_length_5.sol index f632f3bc83..e3ab2189c9 100644 --- a/test/libsolidity/smtCheckerTests/types/static_array_length_5.sol +++ b/test/libsolidity/smtCheckerTests/types/static_array_length_5.sol @@ -11,3 +11,4 @@ contract C { // ---- // Warning 6328: (95-115): CHC: Assertion violation happens here.\nCounterexample:\na = [0, 0]\n\nTransaction trace:\nC.constructor()\nState: a = [0, 0]\nC.f() // Warning 6328: (134-154): CHC: Assertion violation happens here.\nCounterexample:\na = [0, 0]\n\nTransaction trace:\nC.constructor()\nState: a = [0, 0]\nC.f() +// Info 1180: Contract invariant(s) for :C:\n(!(a.length <= 1) && !(a.length >= 3))\n diff --git a/test/libsolidity/smtCheckerTests/types/struct/struct_state_constructor.sol b/test/libsolidity/smtCheckerTests/types/struct/struct_state_constructor.sol index 7c31c616c2..986781b771 100644 --- a/test/libsolidity/smtCheckerTests/types/struct/struct_state_constructor.sol +++ b/test/libsolidity/smtCheckerTests/types/struct/struct_state_constructor.sol @@ -13,3 +13,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Contract invariant(s) for :C:\n(!(s.x <= 41) && !(s.x >= 43))\n diff --git a/test/libsolidity/smtCheckerTests/types/tuple_extra_parens_7.sol b/test/libsolidity/smtCheckerTests/types/tuple_extra_parens_7.sol index f1b1281621..60b3054022 100644 --- a/test/libsolidity/smtCheckerTests/types/tuple_extra_parens_7.sol +++ b/test/libsolidity/smtCheckerTests/types/tuple_extra_parens_7.sol @@ -12,3 +12,4 @@ contract C { // ==== // SMTEngine: all // ---- +// Info 1180: Reentrancy property(ies) for :C:\n!( >= 2)\n( <= 0)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 2)\n = 2 -> Assertion failed at assert(y == 3)\n diff --git a/test/libsolidity/smtCheckerTests/userTypes/mapping_1.sol b/test/libsolidity/smtCheckerTests/userTypes/mapping_1.sol index 52ea828007..120348a046 100644 --- a/test/libsolidity/smtCheckerTests/userTypes/mapping_1.sol +++ b/test/libsolidity/smtCheckerTests/userTypes/mapping_1.sol @@ -6,5 +6,8 @@ contract C { assert(m[a] != 0); // should fail } } +// ==== +// SMTEngine: all +// SMTIgnoreInv: yes // ---- // Warning 6328: (134-151): CHC: Assertion violation happens here.\nCounterexample:\n\na = 0\n\nTransaction trace:\nC.constructor()\nC.f(0) From 4f823c63422ddc1080a31807321ec342f2b1a4d5 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:53:14 +0200 Subject: [PATCH 0030/1748] CLI and JSON tests --- .../model_checker_invariants_all/args | 1 + .../model_checker_invariants_all/err | 15 +++++++++++ .../model_checker_invariants_all/input.sol | 12 +++++++++ .../model_checker_invariants_contract/args | 1 + .../model_checker_invariants_contract/err | 2 ++ .../input.sol | 8 ++++++ .../args | 1 + .../err | 15 +++++++++++ .../input.sol | 12 +++++++++ .../model_checker_invariants_reentrancy/args | 1 + .../model_checker_invariants_reentrancy/err | 10 +++++++ .../input.sol | 9 +++++++ .../model_checker_invariants_wrong/args | 1 + .../model_checker_invariants_wrong/err | 1 + .../model_checker_invariants_wrong/exit | 1 + .../model_checker_invariants_wrong/input.sol | 8 ++++++ .../input.json | 23 ++++++++++++++++ .../output.json | 7 +++++ .../input.json | 27 +++++++++++++++++++ .../output.json | 27 +++++++++++++++++++ .../input.json | 24 +++++++++++++++++ .../output.json | 17 ++++++++++++ .../input.json | 23 ++++++++++++++++ .../output.json | 1 + .../input.json | 23 ++++++++++++++++ .../output.json | 1 + .../input.json | 23 ++++++++++++++++ .../output.json | 1 + 28 files changed, 295 insertions(+) create mode 100644 test/cmdlineTests/model_checker_invariants_all/args create mode 100644 test/cmdlineTests/model_checker_invariants_all/err create mode 100644 test/cmdlineTests/model_checker_invariants_all/input.sol create mode 100644 test/cmdlineTests/model_checker_invariants_contract/args create mode 100644 test/cmdlineTests/model_checker_invariants_contract/err create mode 100644 test/cmdlineTests/model_checker_invariants_contract/input.sol create mode 100644 test/cmdlineTests/model_checker_invariants_contract_reentrancy/args create mode 100644 test/cmdlineTests/model_checker_invariants_contract_reentrancy/err create mode 100644 test/cmdlineTests/model_checker_invariants_contract_reentrancy/input.sol create mode 100644 test/cmdlineTests/model_checker_invariants_reentrancy/args create mode 100644 test/cmdlineTests/model_checker_invariants_reentrancy/err create mode 100644 test/cmdlineTests/model_checker_invariants_reentrancy/input.sol create mode 100644 test/cmdlineTests/model_checker_invariants_wrong/args create mode 100644 test/cmdlineTests/model_checker_invariants_wrong/err create mode 100644 test/cmdlineTests/model_checker_invariants_wrong/exit create mode 100644 test/cmdlineTests/model_checker_invariants_wrong/input.sol create mode 100644 test/cmdlineTests/standard_model_checker_invariants_contract/input.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_contract/output.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/input.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_reentrancy/input.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_wrong_key/input.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_wrong_key/output.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_wrong_type/input.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_wrong_type/output.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/input.json create mode 100644 test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/output.json diff --git a/test/cmdlineTests/model_checker_invariants_all/args b/test/cmdlineTests/model_checker_invariants_all/args new file mode 100644 index 0000000000..389acc6478 --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_all/args @@ -0,0 +1 @@ +--model-checker-engine chc --model-checker-invariants all diff --git a/test/cmdlineTests/model_checker_invariants_all/err b/test/cmdlineTests/model_checker_invariants_all/err new file mode 100644 index 0000000000..47bc04256e --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_all/err @@ -0,0 +1,15 @@ +Warning: Return value of low-level calls not used. + --> model_checker_invariants_all/input.sol:6:3: + | +6 | _a.call(""); + | ^^^^^^^^^^^ + +Info: Contract invariant(s) for model_checker_invariants_all/input.sol:test: +(x <= 0) +Reentrancy property(ies) for model_checker_invariants_all/input.sol:test: +(!(x <= 0) || (x' <= 0)) +((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) +((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) + = 0 -> no errors + = 1 -> Assertion failed at assert(x < 10) + = 3 -> Assertion failed at assert(x < 10) diff --git a/test/cmdlineTests/model_checker_invariants_all/input.sol b/test/cmdlineTests/model_checker_invariants_all/input.sol new file mode 100644 index 0000000000..f8601cf4f4 --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_all/input.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract test { + uint x; + function f(address _a) public { + _a.call(""); + assert(x < 10); + } + function g() public view { + assert(x < 10); + } +} \ No newline at end of file diff --git a/test/cmdlineTests/model_checker_invariants_contract/args b/test/cmdlineTests/model_checker_invariants_contract/args new file mode 100644 index 0000000000..e856a73b9c --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_contract/args @@ -0,0 +1 @@ +--model-checker-engine chc --model-checker-invariants contract diff --git a/test/cmdlineTests/model_checker_invariants_contract/err b/test/cmdlineTests/model_checker_invariants_contract/err new file mode 100644 index 0000000000..a5277bebf9 --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_contract/err @@ -0,0 +1,2 @@ +Info: Contract invariant(s) for model_checker_invariants_contract/input.sol:test: +(x <= 0) diff --git a/test/cmdlineTests/model_checker_invariants_contract/input.sol b/test/cmdlineTests/model_checker_invariants_contract/input.sol new file mode 100644 index 0000000000..3a857d4848 --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_contract/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); + } +} \ No newline at end of file diff --git a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/args b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/args new file mode 100644 index 0000000000..90591a5ae2 --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/args @@ -0,0 +1 @@ +--model-checker-engine chc --model-checker-invariants contract,reentrancy diff --git a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err new file mode 100644 index 0000000000..372143657c --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err @@ -0,0 +1,15 @@ +Warning: Return value of low-level calls not used. + --> model_checker_invariants_contract_reentrancy/input.sol:6:3: + | +6 | _a.call(""); + | ^^^^^^^^^^^ + +Info: Contract invariant(s) for model_checker_invariants_contract_reentrancy/input.sol:test: +(x <= 0) +Reentrancy property(ies) for model_checker_invariants_contract_reentrancy/input.sol:test: +(!(x <= 0) || (x' <= 0)) +((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) +((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) + = 0 -> no errors + = 1 -> Assertion failed at assert(x < 10) + = 3 -> Assertion failed at assert(x < 10) diff --git a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/input.sol b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/input.sol new file mode 100644 index 0000000000..f8601cf4f4 --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/input.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract test { + uint x; + function f(address _a) public { + _a.call(""); + assert(x < 10); + } + function g() public view { + assert(x < 10); + } +} \ No newline at end of file diff --git a/test/cmdlineTests/model_checker_invariants_reentrancy/args b/test/cmdlineTests/model_checker_invariants_reentrancy/args new file mode 100644 index 0000000000..904defe84b --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_reentrancy/args @@ -0,0 +1 @@ +--model-checker-engine chc --model-checker-invariants reentrancy diff --git a/test/cmdlineTests/model_checker_invariants_reentrancy/err b/test/cmdlineTests/model_checker_invariants_reentrancy/err new file mode 100644 index 0000000000..a2fd6075af --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_reentrancy/err @@ -0,0 +1,10 @@ +Warning: Return value of low-level calls not used. + --> model_checker_invariants_reentrancy/input.sol:6:3: + | +6 | _a.call(""); + | ^^^^^^^^^^^ + +Info: Reentrancy property(ies) for model_checker_invariants_reentrancy/input.sol:test: +((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) + = 0 -> no errors + = 1 -> Assertion failed at assert(x < 10) diff --git a/test/cmdlineTests/model_checker_invariants_reentrancy/input.sol b/test/cmdlineTests/model_checker_invariants_reentrancy/input.sol new file mode 100644 index 0000000000..f21d4d4c8f --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_reentrancy/input.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract test { + uint x; + function f(address _a) public { + _a.call(""); + assert(x < 10); + } +} \ No newline at end of file diff --git a/test/cmdlineTests/model_checker_invariants_wrong/args b/test/cmdlineTests/model_checker_invariants_wrong/args new file mode 100644 index 0000000000..ae601a0444 --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_wrong/args @@ -0,0 +1 @@ +--model-checker-engine chc --model-checker-invariants what diff --git a/test/cmdlineTests/model_checker_invariants_wrong/err b/test/cmdlineTests/model_checker_invariants_wrong/err new file mode 100644 index 0000000000..1dc94780db --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_wrong/err @@ -0,0 +1 @@ +Invalid option for --model-checker-invariants: what diff --git a/test/cmdlineTests/model_checker_invariants_wrong/exit b/test/cmdlineTests/model_checker_invariants_wrong/exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_wrong/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/model_checker_invariants_wrong/input.sol b/test/cmdlineTests/model_checker_invariants_wrong/input.sol new file mode 100644 index 0000000000..17bf3b749c --- /dev/null +++ b/test/cmdlineTests/model_checker_invariants_wrong/input.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract test { + uint x; + function g() public view { + assert(x < 10); + } +} \ No newline at end of file diff --git a/test/cmdlineTests/standard_model_checker_invariants_contract/input.json b/test/cmdlineTests/standard_model_checker_invariants_contract/input.json new file mode 100644 index 0000000000..d47c93de2a --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_contract/input.json @@ -0,0 +1,23 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test { + uint x; + function f() public view { + assert(x < 10); + } + }" + } + }, + "settings": + { + "modelChecker": + { + "engine": "chc", + "invariants": ["contract"] + } + } +} diff --git a/test/cmdlineTests/standard_model_checker_invariants_contract/output.json b/test/cmdlineTests/standard_model_checker_invariants_contract/output.json new file mode 100644 index 0000000000..1cd236baf0 --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_contract/output.json @@ -0,0 +1,7 @@ +{"errors":[{"component":"general","errorCode":"1180","formattedMessage":"Info: Contract invariant(s) for A:test: +(x <= 0) + + +","message":"Contract invariant(s) for A:test: +(x <= 0) +","severity":"info","type":"Info"}],"sources":{"A":{"id":0}}} diff --git a/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/input.json b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/input.json new file mode 100644 index 0000000000..56139e6a5a --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/input.json @@ -0,0 +1,27 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "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 g() public view { + assert(x < 10); + } + }" + } + }, + "settings": + { + "modelChecker": + { + "engine": "chc", + "invariants": ["contract", "reentrancy"] + } + } +} diff --git a/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json new file mode 100644 index 0000000000..433648d0b9 --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json @@ -0,0 +1,27 @@ +{"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^^^^^^^^^^^ + +","message":"Return value of low-level calls not used.","severity":"warning","sourceLocation":{"end":143,"file":"A","start":132},"type":"Warning"},{"component":"general","errorCode":"1180","formattedMessage":"Info: Contract invariant(s) for A:test: +(x <= 0) +Reentrancy property(ies) for A:test: +(!(x <= 0) || (x' <= 0)) +((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) +((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) + = 0 -> no errors + = 1 -> Assertion failed at assert(x < 10) + = 3 -> Assertion failed at assert(x < 10) + + +","message":"Contract invariant(s) for A:test: +(x <= 0) +Reentrancy property(ies) for A:test: +(!(x <= 0) || (x' <= 0)) +((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) +((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) + = 0 -> no errors + = 1 -> Assertion failed at assert(x < 10) + = 3 -> Assertion failed at assert(x < 10) +","severity":"info","type":"Info"}],"sources":{"A":{"id":0}}} diff --git a/test/cmdlineTests/standard_model_checker_invariants_reentrancy/input.json b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/input.json new file mode 100644 index 0000000000..1f98000b0e --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/input.json @@ -0,0 +1,24 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "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); + } + }" + } + }, + "settings": + { + "modelChecker": + { + "engine": "chc", + "invariants": ["reentrancy"] + } + } +} diff --git a/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json new file mode 100644 index 0000000000..4158c3ae10 --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json @@ -0,0 +1,17 @@ +{"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^^^^^^^^^^^ + +","message":"Return value of low-level calls not used.","severity":"warning","sourceLocation":{"end":143,"file":"A","start":132},"type":"Warning"},{"component":"general","errorCode":"1180","formattedMessage":"Info: Reentrancy property(ies) for A:test: +((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) + = 0 -> no errors + = 1 -> Assertion failed at assert(x < 10) + + +","message":"Reentrancy property(ies) for A:test: +((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) + = 0 -> no errors + = 1 -> Assertion failed at assert(x < 10) +","severity":"info","type":"Info"}],"sources":{"A":{"id":0}}} diff --git a/test/cmdlineTests/standard_model_checker_invariants_wrong_key/input.json b/test/cmdlineTests/standard_model_checker_invariants_wrong_key/input.json new file mode 100644 index 0000000000..e8ee6aba63 --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_wrong_key/input.json @@ -0,0 +1,23 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test { + uint x; + function f() public view { + assert(x < 10); + } + }" + } + }, + "settings": + { + "modelChecker": + { + "engine": "chc", + "invariants": ["what"] + } + } +} diff --git a/test/cmdlineTests/standard_model_checker_invariants_wrong_key/output.json b/test/cmdlineTests/standard_model_checker_invariants_wrong_key/output.json new file mode 100644 index 0000000000..7758b29ca2 --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_wrong_key/output.json @@ -0,0 +1 @@ +{"errors":[{"component":"general","formattedMessage":"Invalid model checker invariants requested.","message":"Invalid model checker invariants requested.","severity":"error","type":"JSONError"}]} diff --git a/test/cmdlineTests/standard_model_checker_invariants_wrong_type/input.json b/test/cmdlineTests/standard_model_checker_invariants_wrong_type/input.json new file mode 100644 index 0000000000..54fc96d46c --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_wrong_type/input.json @@ -0,0 +1,23 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test { + uint x; + function f() public view { + assert(x < 10); + } + }" + } + }, + "settings": + { + "modelChecker": + { + "engine": "chc", + "invariants": [2] + } + } +} diff --git a/test/cmdlineTests/standard_model_checker_invariants_wrong_type/output.json b/test/cmdlineTests/standard_model_checker_invariants_wrong_type/output.json new file mode 100644 index 0000000000..5ad18a3b1c --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_wrong_type/output.json @@ -0,0 +1 @@ +{"errors":[{"component":"general","formattedMessage":"Every invariant type in settings.modelChecker.invariants must be a string.","message":"Every invariant type in settings.modelChecker.invariants must be a string.","severity":"error","type":"JSONError"}]} diff --git a/test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/input.json b/test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/input.json new file mode 100644 index 0000000000..f7522e6e5e --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/input.json @@ -0,0 +1,23 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test { + uint x; + function f() public view { + assert(x < 10); + } + }" + } + }, + "settings": + { + "modelChecker": + { + "engine": "chc", + "invariants": 2 + } + } +} 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 new file mode 100644 index 0000000000..b4fba3576b --- /dev/null +++ b/test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/output.json @@ -0,0 +1 @@ +{"errors":[{"component":"general","formattedMessage":"settings.modelChecker.invariants must be an array.","message":"settings.modelChecker.invariants must be an array.","severity":"error","type":"JSONError"}]} From d04ad57ee79ace9722ccac0122928f5836a5940b Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:53:20 +0200 Subject: [PATCH 0031/1748] Docs --- docs/smtchecker.rst | 19 ++++++++++++++++++- docs/using-the-compiler.rst | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/smtchecker.rst b/docs/smtchecker.rst index a9732d05ee..791659897e 100644 --- a/docs/smtchecker.rst +++ b/docs/smtchecker.rst @@ -412,7 +412,7 @@ is already "locked", so it would not be possible to change the value of ``x``, regardless of what the unknown called code does. If we "forget" to use the ``mutex`` modifier on function ``set``, the -SMTChecker is able to synthesize the behavior of the externally called code so +SMTChecker is able to synthesize the behaviour of the externally called code so that the assertion fails: .. code-block:: text @@ -518,6 +518,23 @@ which has the following form: "source2.sol": ["contract2", "contract3"] } +Reported Inferred Inductive Invariants +====================================== + +For properties that were proved safe with the CHC engine, +the SMTChecker can retrieve inductive invariants that were inferred by the Horn +solver as part of the proof. +Currently two types of invariants can be reported to the user: + +- Contract Invariants: these are properties over the contract's state variables + that are true before and after every possible transaction that the contract may ever run. For example, ``x >= y``, where ``x`` and ``y`` are a contract's state variables. +- Reentrancy Properties: they represent the behavior of the contract + in the presence of external calls to unknown code. These properties can express a relation + between the value of the state variables before and after the external call, where the external call is free to do anything, including making reentrant calls to the analyzed contract. Primed variables represent the state variables' values after said external call. Example: ``lock -> x = x'``. + +The user can choose the type of invariants to be reported using the CLI option ``--model-checker-invariants "contract,reentrancy"`` or as an array in the field ``settings.modelChecker.invariants`` in the :ref:`JSON input`. +By default the SMTChecker does not report invariants. + Division and Modulo With Slack Variables ======================================== diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 88da5d5e69..c6c40cacc0 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -418,6 +418,8 @@ Input Description "divModWithSlacks": true, // Choose which model checker engine to use: all (default), bmc, chc, none. "engine": "chc", + // Choose which types of invariants should be reported to the user: contract, reentrancy. + "invariants": ["contract", "reentrancy"], // Choose whether to output all unproved targets. The default is `false`. "showUnproved": true, // Choose which solvers should be used, if available. From 902a2e232bc2907f198f706d0faa2d758e58efb0 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 6 Oct 2021 11:53:30 +0200 Subject: [PATCH 0032/1748] Changelog --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index e79b13e6ef..c5211922d6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Compiler Features: * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. * Commandline Interface: Use different colors when printing errors, warnings and infos. * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. + * SMTChecker: Report contract invariants and reentrancy properties. This can be enabled via the CLI option ``--model-checker-invariants`` or the Standard JSON option ``settings.modelChecker.invariants``. * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. * Standard JSON: Add ``settings.debug.debugInfo`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. From f588dd34a9bcf2faeeeaec57f741a0f7f12158ee Mon Sep 17 00:00:00 2001 From: Marenz Date: Tue, 26 Oct 2021 14:56:13 +0200 Subject: [PATCH 0033/1748] Sort bugfixes in changelog --- Changelog.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index c5211922d6..c709229424 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,15 +16,15 @@ Compiler Features: Bugfixes: * Code Generator: Fix constructor source mappings for immutables. + * Commandline Interface: Disallow ``--error-recovery`` option outside of the compiler mode. + * Commandline Interface: Don't return zero exit code when writing linked files to disk fails. * Commandline Interface: Fix extra newline character being appended to sources passed through standard input, affecting their hashes. * Commandline Interface: Report output selection options unsupported by the selected input mode instead of ignoring them. - * Commandline Interface: Don't return zero exit code when writing linked files to disk fails. - * Commandline Interface: Disallow ``--error-recovery`` option outside of the compiler mode. + * Commandline Interface: When linking only accept exact matches for library names passed to the ``--libraries`` option. Library names not prefixed with a file name used to match any library with that name. * SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``). * TypeChecker: Fix internal error when using user defined value types in public library functions. * Yul Assembler: Fix internal error when function names are not unique. * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts. - * Commandline Interface: When linking only accept exact matches for library names passed to the ``--libraries`` option. Library names not prefixed with a file name used to match any library with that name. From b8aed7ca867c1b9cc7ae02f7b129082b9c218e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 25 Oct 2021 12:59:55 +0200 Subject: [PATCH 0034/1748] Run external tests on latest upstream code where possible --- test/externalTests/ens.sh | 2 +- test/externalTests/zeppelin.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index a19ce859d6..90c96d5a50 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -33,7 +33,7 @@ function ens_test export OPTIMIZER_LEVEL=1 export CONFIG="truffle-config.js" - truffle_setup "$SOLJSON" https://github.com/solidity-external-tests/ens.git master_080 + truffle_setup "$SOLJSON" https://github.com/ensdomains/ens.git master # Use latest Truffle. Older versions crash on the output from 0.8.0. force_truffle_version ^5.1.55 diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 8d8cb48457..97da3d47bf 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -33,7 +33,7 @@ function zeppelin_test OPTIMIZER_LEVEL=1 CONFIG="truffle-config.js" - truffle_setup "$SOLJSON" https://github.com/solidity-external-tests/openzeppelin-contracts.git master_080 + truffle_setup "$SOLJSON" https://github.com/OpenZeppelin/openzeppelin-contracts.git master run_install "$SOLJSON" install_fn truffle_run_test "$SOLJSON" compile_fn test_fn From 14210825b1fd31c2a1ac6f983d4129c4ec9c8619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 25 Oct 2021 13:10:15 +0200 Subject: [PATCH 0035/1748] externalTests/README: Recommend using upstream repository directly when possible --- test/externalTests/README.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/test/externalTests/README.md b/test/externalTests/README.md index a6c160846a..76e39a79b0 100644 --- a/test/externalTests/README.md +++ b/test/externalTests/README.md @@ -13,16 +13,17 @@ these projects *can* be upgraded at all. ### Recommended workflow #### Adding a new external project -1. Create a fork of the upstream repository in https://github.com/solidity-external-tests/. If the - project consists of several repositories, fork them all. -2. Remove all the branches except for main one (`master`, `develop`, `main`, etc). This branch is - going to be always kept up to date with the upstream repository and should not contain any extra - commits. +1. If the upstream code cannot be compiled without modifications, create a fork of the repository + in https://github.com/solidity-external-tests/. +2. In our fork, remove all the branches except for main one (`master`, `develop`, `main`, etc). + This branch is going to be always kept up to date with the upstream repository and should not + contain any extra commits. - If the project is not up to date with the latest compiler version but has a branch that is, try to use that branch instead. -3. Create a new branch named after the main branch and the compiler version from our `develop` - branch. E.g. if the latest Solidity version is 0.7.5 and the main branch of the external project - is called `master`, create `master_070`. This is where we will be adding our own commits. +3. In our fork, create a new branch named after the main branch and the compiler version from our + `develop` branch. + E.g. if the latest Solidity version is 0.7.5 and the main branch of the external project + is called `master`, create `master_070`. This is where we will be adding our own commits. 4. Create a script for compiling/testing the project and put it in `test/externalTests/` in the Solidity repository. - The script should apply workarounds necessary to make the project actually use the compiler @@ -39,12 +40,12 @@ these projects *can* be upgraded at all. and add necessary workarounds there. Continuing the example above, the new branch would be called `master_080` and should be rebased on top of `master_070`. - The fewer commits in these branches, the better. Ideally, any changes needed to make the compiler - work should be submitted upstream and our branches should just be tracking the main upstream - branch without any extra commits. + work should be submitted upstream and our scripts should be using the upstream repository + directly. #### Updating external projects for a PR that introduces breaking changes in the compiler If a PR to our `breaking` branch introduces changes that will make an external project no longer -compile or pass its tests, the fork needs to be modified: +compile or pass its tests, the fork needs to be modified (or created if it does not yet exist): - If a branch specific to the compiler version from `breaking` does not exist yet: 1. Create the branch. It should be based on the version-specific branch used on `develop`. 2. Make your PR modify the project script in `test/externalScripts/` to use the new branch. @@ -84,7 +85,7 @@ to use the updated copies of the branches and can be discarded aferwards without When a non-backwards-compatible version becomes the most recent release, `breaking` branch gets merged into `develop` which automatically results in a switch to the newer version-specific branches if they exist. If no changes on our part were necessary, it is completely fine to keep using -e.g. the `master_060` of an external project in in Solidity 0.8.x. +e.g. the `master_060` of an external project in Solidity 0.8.x. Since each project is handled separately, this approach may result in a mix of version-specific branches between different external projects. For example, in one project we could could have `master_050` on From 9428dbc94fe43c0132d1ed6c37cf755fe9855723 Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Mon, 25 Oct 2021 11:58:49 +0100 Subject: [PATCH 0036/1748] Moved storage size assert to TypeChecker from DeclarationTypeChecker --- Changelog.md | 2 ++ libsolidity/analysis/DeclarationTypeChecker.cpp | 1 - libsolidity/analysis/TypeChecker.cpp | 8 ++++++++ libsolidity/analysis/TypeChecker.h | 1 + .../userDefinedValueType/forward_reference_array.sol | 4 ++++ 5 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_array.sol diff --git a/Changelog.md b/Changelog.md index c709229424..ff183e22b2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -23,6 +23,8 @@ Bugfixes: * Commandline Interface: When linking only accept exact matches for library names passed to the ``--libraries`` option. Library names not prefixed with a file name used to match any library with that name. * SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``). * TypeChecker: Fix internal error when using user defined value types in public library functions. + * TypeChecker: Fix internal error when using arrays and structs with user defined value types before declaration. + * TypeChecker: Improved error message for constant variables with (nested) mapping types. * Yul Assembler: Fix internal error when function names are not unique. * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts. diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index b015939e21..d531fd77fa 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -289,7 +289,6 @@ void DeclarationTypeChecker::endVisit(ArrayTypeName const& _typeName) return; } - solAssert(baseType->storageBytes() != 0, "Illegal base type of storage size zero for array."); if (Expression const* length = _typeName.length()) { optional lengthValue; diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index f11756b25b..0b5f97719b 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1220,6 +1220,14 @@ void TypeChecker::endVisit(RevertStatement const& _revert) m_errorReporter.typeError(1885_error, errorCall.expression().location(), "Expression has to be an error."); } +void TypeChecker::endVisit(ArrayTypeName const& _typeName) +{ + solAssert( + _typeName.baseType().annotation().type && + _typeName.baseType().annotation().type->storageBytes() != 0, + "Illegal base type of storage size zero for array." + ); +} bool TypeChecker::visit(VariableDeclarationStatement const& _statement) { diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index bf50392042..f0820d930e 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -119,6 +119,7 @@ class TypeChecker: private ASTConstVisitor void endVisit(InheritanceSpecifier const& _inheritance) override; void endVisit(ModifierDefinition const& _modifier) override; bool visit(FunctionDefinition const& _function) override; + void endVisit(ArrayTypeName const& _typeName) override; bool visit(VariableDeclaration const& _variable) override; /// We need to do this manually because we want to pass the bases of the current contract in /// case this is a base constructor call. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_array.sol b/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_array.sol new file mode 100644 index 0000000000..884fb2b5d6 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_array.sol @@ -0,0 +1,4 @@ +contract C { + Left[] pu1; +} +type Left is bytes2; From 51009c005d0934f6e32e77fa0277ad847defb69e Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Tue, 26 Oct 2021 18:31:13 +0200 Subject: [PATCH 0037/1748] Moved a canBeStored assert for struct members to TypeChecker This is to avoid a assert from failing for forward declared user defined value types. --- libsolidity/analysis/DeclarationTypeChecker.cpp | 1 - libsolidity/analysis/TypeChecker.cpp | 10 ++++++++++ libsolidity/analysis/TypeChecker.h | 1 + .../userDefinedValueType/forward_reference_struct.sol | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_struct.sol diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index d531fd77fa..d5392ef84b 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -100,7 +100,6 @@ bool DeclarationTypeChecker::visit(StructDefinition const& _struct) m_recursiveStructSeen = false; member->accept(*this); solAssert(member->annotation().type, ""); - solAssert(member->annotation().type->canBeStored(), "Type cannot be used in struct."); if (m_recursiveStructSeen) hasRecursiveChild = true; } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 0b5f97719b..83a9da55c7 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -621,6 +621,16 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) return false; } +void TypeChecker::endVisit(StructDefinition const& _struct) +{ + for (auto const& member: _struct.members()) + solAssert( + member->annotation().type && + member->annotation().type->canBeStored(), + "Type cannot be used in struct." + ); +} + void TypeChecker::visitManually( ModifierInvocation const& _modifier, vector const& _bases diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index f0820d930e..ba445ffbb0 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -121,6 +121,7 @@ class TypeChecker: private ASTConstVisitor bool visit(FunctionDefinition const& _function) override; void endVisit(ArrayTypeName const& _typeName) override; bool visit(VariableDeclaration const& _variable) override; + void endVisit(StructDefinition const& _struct) override; /// We need to do this manually because we want to pass the bases of the current contract in /// case this is a base constructor call. void visitManually(ModifierInvocation const& _modifier, std::vector const& _bases); diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_struct.sol b/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_struct.sol new file mode 100644 index 0000000000..b99cff215f --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_struct.sol @@ -0,0 +1,3 @@ +struct S { U u; } +contract C { S s; } +type U is address; From 8815d6f5f09a0e4bd54190ab148f5ca3659a7c02 Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Tue, 26 Oct 2021 18:29:46 +0200 Subject: [PATCH 0038/1748] Moved a check related to constants to TypeChecker And added a proper error message when constant types containing (nested) mapping types are used. --- .../analysis/DeclarationTypeChecker.cpp | 18 ++++++++++-------- libsolidity/analysis/TypeChecker.cpp | 9 +++++++++ libsolidity/ast/Types.h | 2 ++ .../constantEvaluator/type_reference.sol | 1 - .../type_reference_in_contract.sol | 1 - .../syntaxTests/constants/mapping_constant.sol | 2 +- .../syntaxTests/constants/struct_constant.sol | 2 +- .../const_struct_with_mapping.sol | 2 +- .../105_constant_input_parameter.sol | 1 - .../171_assignment_to_const_array_vars.sol | 2 +- .../173_constant_struct.sol | 2 +- .../nameAndTypeResolution/constant_mapping.sol | 4 +--- .../constant_nested_mapping.sol | 2 +- .../parsing/location_specifiers_for_params.sol | 1 - ...reference_constant_variable_declaration.sol | 2 ++ 15 files changed, 30 insertions(+), 21 deletions(-) create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_constant_variable_declaration.sol diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index d5392ef84b..076155366b 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -437,14 +437,16 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) type = TypeProvider::withLocation(ref, typeLoc, isPointer); } - if (_variable.isConstant() && !type->isValueType()) - { - bool allowed = false; - if (auto arrayType = dynamic_cast(type)) - allowed = arrayType->isByteArray(); - if (!allowed) - m_errorReporter.fatalDeclarationError(9259_error, _variable.location(), "Constants of non-value type not yet implemented."); - } + if ( + _variable.isConstant() && + !dynamic_cast(type) && + type->containsNestedMapping() + ) + m_errorReporter.fatalDeclarationError( + 3530_error, + _variable.location(), + "The type contains a (nested) mapping and therefore cannot be a constant." + ); _variable.annotation().type = type; } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 83a9da55c7..05fdc489bb 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -530,6 +530,15 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) } if (_variable.isConstant()) { + if (!varType->isValueType()) + { + bool allowed = false; + if (auto arrayType = dynamic_cast(varType)) + allowed = arrayType->isByteArray(); + if (!allowed) + m_errorReporter.fatalTypeError(9259_error, _variable.location(), "Constants of non-value type not yet implemented."); + } + if (!_variable.value()) m_errorReporter.typeError(4266_error, _variable.location(), "Uninitialized \"constant\" variable."); else if (!*_variable.value()->annotation().isPure) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 334e69ba15..b08694820b 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -1124,6 +1124,8 @@ class UserDefinedValueType: public Type bool containsNestedMapping() const override { solAssert(nameable(), "Called for a non nameable type."); + // DeclarationTypeChecker::endVisit(VariableDeclaration const&) + // assumes that this will never be true. solAssert(!underlyingType().containsNestedMapping(), ""); return false; } diff --git a/test/libsolidity/syntaxTests/constantEvaluator/type_reference.sol b/test/libsolidity/syntaxTests/constantEvaluator/type_reference.sol index 4ad0a0c4b4..585c005f62 100644 --- a/test/libsolidity/syntaxTests/constantEvaluator/type_reference.sol +++ b/test/libsolidity/syntaxTests/constantEvaluator/type_reference.sol @@ -1,4 +1,3 @@ int[L] constant L = 6; // ---- // TypeError 5462: (4-5): Invalid array length, expected integer literal or constant expression. -// DeclarationError 9259: (0-21): Constants of non-value type not yet implemented. diff --git a/test/libsolidity/syntaxTests/constantEvaluator/type_reference_in_contract.sol b/test/libsolidity/syntaxTests/constantEvaluator/type_reference_in_contract.sol index 7ce1a7ad39..9073f6ac16 100644 --- a/test/libsolidity/syntaxTests/constantEvaluator/type_reference_in_contract.sol +++ b/test/libsolidity/syntaxTests/constantEvaluator/type_reference_in_contract.sol @@ -3,4 +3,3 @@ contract C { } // ---- // TypeError 5462: (21-22): Invalid array length, expected integer literal or constant expression. -// DeclarationError 9259: (17-38): Constants of non-value type not yet implemented. diff --git a/test/libsolidity/syntaxTests/constants/mapping_constant.sol b/test/libsolidity/syntaxTests/constants/mapping_constant.sol index 5821d0d569..4d80fb43e3 100644 --- a/test/libsolidity/syntaxTests/constants/mapping_constant.sol +++ b/test/libsolidity/syntaxTests/constants/mapping_constant.sol @@ -1,3 +1,3 @@ mapping(uint => uint) constant b = b; // ---- -// DeclarationError 9259: (0-36): Constants of non-value type not yet implemented. +// DeclarationError 3530: (0-36): The type contains a (nested) mapping and therefore cannot be a constant. diff --git a/test/libsolidity/syntaxTests/constants/struct_constant.sol b/test/libsolidity/syntaxTests/constants/struct_constant.sol index 42f4584ed4..8d750beb6a 100644 --- a/test/libsolidity/syntaxTests/constants/struct_constant.sol +++ b/test/libsolidity/syntaxTests/constants/struct_constant.sol @@ -1,4 +1,4 @@ struct S { uint x; } S constant s; // ---- -// DeclarationError 9259: (21-33): Constants of non-value type not yet implemented. +// TypeError 9259: (21-33): Constants of non-value type not yet implemented. diff --git a/test/libsolidity/syntaxTests/iceRegressionTests/const_struct_with_mapping.sol b/test/libsolidity/syntaxTests/iceRegressionTests/const_struct_with_mapping.sol index 2ee03b09ea..f8e0896c3f 100644 --- a/test/libsolidity/syntaxTests/iceRegressionTests/const_struct_with_mapping.sol +++ b/test/libsolidity/syntaxTests/iceRegressionTests/const_struct_with_mapping.sol @@ -5,4 +5,4 @@ contract C { S public constant e = 0x1212121212121212121212121212121212121212; } // ---- -// DeclarationError 9259: (71-135): Constants of non-value type not yet implemented. +// DeclarationError 3530: (71-135): The type contains a (nested) mapping and therefore cannot be a constant. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol index cac87c3ddc..aaf6f620a6 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol @@ -3,4 +3,3 @@ contract test { } // ---- // DeclarationError 1788: (31-55): The "constant" keyword can only be used for state variables or variables at file level. -// DeclarationError 9259: (31-55): Constants of non-value type not yet implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/171_assignment_to_const_array_vars.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/171_assignment_to_const_array_vars.sol index cb39b004b2..81b9eab8a7 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/171_assignment_to_const_array_vars.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/171_assignment_to_const_array_vars.sol @@ -2,4 +2,4 @@ contract C { uint[3] constant x = [uint(1), 2, 3]; } // ---- -// DeclarationError 9259: (17-53): Constants of non-value type not yet implemented. +// TypeError 9259: (17-53): Constants of non-value type not yet implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/173_constant_struct.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/173_constant_struct.sol index b9b798431e..d32dd2768f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/173_constant_struct.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/173_constant_struct.sol @@ -3,4 +3,4 @@ contract C { S constant x = S(5, new uint[](4)); } // ---- -// DeclarationError 9259: (52-86): Constants of non-value type not yet implemented. +// TypeError 9259: (52-86): Constants of non-value type not yet implemented. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_mapping.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_mapping.sol index 12d2d9105d..7539a99cbe 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_mapping.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_mapping.sol @@ -1,7 +1,5 @@ contract C { - // This should probably have a better error message at some point. - // Constant mappings should not be possible in general. mapping(uint => uint) constant x; } // ---- -// DeclarationError 9259: (148-180): Constants of non-value type not yet implemented. +// DeclarationError 3530: (17-49): The type contains a (nested) mapping and therefore cannot be a constant. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_nested_mapping.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_nested_mapping.sol index fcc8a432b0..81e6e6b152 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_nested_mapping.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_nested_mapping.sol @@ -5,4 +5,4 @@ contract C { S public constant c; } // ---- -// DeclarationError 9259: (71-90): Constants of non-value type not yet implemented. +// DeclarationError 3530: (71-90): The type contains a (nested) mapping and therefore cannot be a constant. diff --git a/test/libsolidity/syntaxTests/parsing/location_specifiers_for_params.sol b/test/libsolidity/syntaxTests/parsing/location_specifiers_for_params.sol index 8e1ca503c0..7d3dd56405 100644 --- a/test/libsolidity/syntaxTests/parsing/location_specifiers_for_params.sol +++ b/test/libsolidity/syntaxTests/parsing/location_specifiers_for_params.sol @@ -3,4 +3,3 @@ contract Foo { } // ---- // DeclarationError 1788: (30-55): The "constant" keyword can only be used for state variables or variables at file level. -// DeclarationError 9259: (30-55): Constants of non-value type not yet implemented. diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_constant_variable_declaration.sol b/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_constant_variable_declaration.sol new file mode 100644 index 0000000000..a459698a70 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_constant_variable_declaration.sol @@ -0,0 +1,2 @@ +MyInt constant x = MyInt.wrap(20); +type MyInt is int; From 61519da4f0091dd2dfd421b6654dc78e9440ff6e Mon Sep 17 00:00:00 2001 From: Marenz Date: Wed, 27 Oct 2021 14:16:50 +0200 Subject: [PATCH 0039/1748] Fix wrong path to isoltest in docs --- docs/contributing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index ffb1d345c5..4844eaae3c 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -212,7 +212,7 @@ editing of failing contracts using your preferred text editor. Let's try to brea // ---- // DeclarationError: (36-52): Identifier already declared. -Running ``./build/test/isoltest`` again results in a test failure: +Running ``./build/test/tools/isoltest`` again results in a test failure: .. code-block:: text From dce13fbb6a48c1a62672fa9e057772bafbdf3828 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 25 Oct 2021 16:35:51 +0200 Subject: [PATCH 0040/1748] Fix use-after-free bug. --- libyul/ControlFlowSideEffectsCollector.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libyul/ControlFlowSideEffectsCollector.cpp b/libyul/ControlFlowSideEffectsCollector.cpp index 047480f144..f907f83f5b 100644 --- a/libyul/ControlFlowSideEffectsCollector.cpp +++ b/libyul/ControlFlowSideEffectsCollector.cpp @@ -212,7 +212,8 @@ ControlFlowSideEffectsCollector::ControlFlowSideEffectsCollector( if (calledSideEffects->canRevert) sideEffects.canRevert = true; - for (YulString callee: util::valueOrDefault(m_functionCalls, _function)) + set emptySet; + for (YulString callee: util::valueOrDefault(m_functionCalls, _function, emptySet)) _recurse(callee, _recurse); }; for (auto const& call: calls) From eb2425bd7c14db2d98ca06a50586ecc8093b0652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 27 Oct 2021 18:02:26 +0200 Subject: [PATCH 0041/1748] isoltest: Fix gas tests always being enforced regardless of evm version --- test/tools/IsolTestOptions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/tools/IsolTestOptions.cpp b/test/tools/IsolTestOptions.cpp index 7f00e88f67..d2323ec166 100644 --- a/test/tools/IsolTestOptions.cpp +++ b/test/tools/IsolTestOptions.cpp @@ -60,7 +60,6 @@ IsolTestOptions::IsolTestOptions(): CommonOptions(description) { enforceViaYul = true; - enforceGasTest = (evmVersion() == langutil::EVMVersion{}); } void IsolTestOptions::addOptions() @@ -84,6 +83,8 @@ bool IsolTestOptions::parse(int _argc, char const* const* _argv) return false; } + enforceGasTest = enforceGasTest || (evmVersion() == langutil::EVMVersion{}); + return res; } From a0394316274b9811be7d3c98c0ce687dfcb10e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 27 Oct 2021 18:20:04 +0200 Subject: [PATCH 0042/1748] isoltest: Do not try to enforce gas costs when ABIEncoderV1 is used --- test/tools/IsolTestOptions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tools/IsolTestOptions.cpp b/test/tools/IsolTestOptions.cpp index d2323ec166..cdd1b85ab1 100644 --- a/test/tools/IsolTestOptions.cpp +++ b/test/tools/IsolTestOptions.cpp @@ -83,7 +83,7 @@ bool IsolTestOptions::parse(int _argc, char const* const* _argv) return false; } - enforceGasTest = enforceGasTest || (evmVersion() == langutil::EVMVersion{}); + enforceGasTest = enforceGasTest || (evmVersion() == langutil::EVMVersion{} && !useABIEncoderV1); return res; } From f4421f1b695ce4798927f30896743408319eddb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 27 Oct 2021 19:52:36 +0200 Subject: [PATCH 0043/1748] Disable metadata in syntax tests --- test/libsolidity/SyntaxTest.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp index 2a70c35ab4..4998b628b3 100644 --- a/test/libsolidity/SyntaxTest.cpp +++ b/test/libsolidity/SyntaxTest.cpp @@ -77,6 +77,8 @@ void SyntaxTest::setupCompiler() OptimiserSettings::full() : OptimiserSettings::minimal() ); + compiler().setMetadataFormat(CompilerStack::MetadataFormat::NoMetadata); + compiler().setMetadataHash(CompilerStack::MetadataHash::None); } void SyntaxTest::parseAndAnalyze() From 79ffa16a61dc866f500551ab2213ad2387f38d9c Mon Sep 17 00:00:00 2001 From: David Dzhalaev <72649244+DavidRomanovizc@users.noreply.github.com> Date: Fri, 22 Oct 2021 00:41:22 +0300 Subject: [PATCH 0044/1748] Improve error message for contract size limit error --- libsolidity/interface/CompilerStack.cpp | 5 ++++- test/libsolidity/syntaxTests/bytecode_too_large.sol | 6 ++++-- .../syntaxTests/bytecode_too_large_abiencoder_v1.sol | 12 ++++++++++++ .../syntaxTests/bytecode_too_large_byzantium.sol | 10 ++++++++++ .../syntaxTests/bytecode_too_large_homestead.sol | 9 +++++++++ 5 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/syntaxTests/bytecode_too_large_abiencoder_v1.sol create mode 100644 test/libsolidity/syntaxTests/bytecode_too_large_byzantium.sol create mode 100644 test/libsolidity/syntaxTests/bytecode_too_large_homestead.sol diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9fa3cb1645..9ec3a402e6 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -83,6 +83,7 @@ #include #include #include +#include using namespace std; using namespace solidity; @@ -1248,7 +1249,9 @@ void CompilerStack::assemble( m_errorReporter.warning( 5574_error, _contract.location(), - "Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). " + "Contract code size is "s + + to_string(compiledContract.runtimeObject.bytecode.size()) + + " bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). " "This contract may not be deployable on mainnet. " "Consider enabling the optimizer (with a low \"runs\" value!), " "turning off revert strings, or using libraries." diff --git a/test/libsolidity/syntaxTests/bytecode_too_large.sol b/test/libsolidity/syntaxTests/bytecode_too_large.sol index 58446e0daf..55d637bfbd 100644 --- a/test/libsolidity/syntaxTests/bytecode_too_large.sol +++ b/test/libsolidity/syntaxTests/bytecode_too_large.sol @@ -1,3 +1,5 @@ +pragma abicoder v2; + contract test { function f() public pure returns (string memory ret) { // 27000 bytes long data @@ -5,6 +7,6 @@ contract test { } } // ==== -// EVMVersion: >=spuriousDragon +// EVMVersion: >byzantium // ---- -// Warning 5574: (0-27133): Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. +// Warning 5574: (21-27154): Contract code size is 27199 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. diff --git a/test/libsolidity/syntaxTests/bytecode_too_large_abiencoder_v1.sol b/test/libsolidity/syntaxTests/bytecode_too_large_abiencoder_v1.sol new file mode 100644 index 0000000000..69dc7ebd0c --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecode_too_large_abiencoder_v1.sol @@ -0,0 +1,12 @@ +pragma abicoder v1; + +contract test { + function f() public pure returns (string memory ret) { + // 27000 bytes long data + ret = "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................"; + } +} +// ==== +// EVMVersion: >byzantium +// ---- +// Warning 5574: (21-27154): Contract code size is 27209 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. diff --git a/test/libsolidity/syntaxTests/bytecode_too_large_byzantium.sol b/test/libsolidity/syntaxTests/bytecode_too_large_byzantium.sol new file mode 100644 index 0000000000..a95ed192a3 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecode_too_large_byzantium.sol @@ -0,0 +1,10 @@ +contract test { + function f() public pure returns (string memory ret) { + // 27000 bytes long data + ret = "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................"; + } +} +// ==== +// EVMVersion: =byzantium +// ---- +// Warning 5574: (0-27133): Contract code size is 27227 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries. diff --git a/test/libsolidity/syntaxTests/bytecode_too_large_homestead.sol b/test/libsolidity/syntaxTests/bytecode_too_large_homestead.sol new file mode 100644 index 0000000000..946f5e8b41 --- /dev/null +++ b/test/libsolidity/syntaxTests/bytecode_too_large_homestead.sol @@ -0,0 +1,9 @@ +contract test { + function f() public pure returns (string memory ret) { + // 27000 bytes long data + ret = "........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................"; + } +} +// ==== +// EVMVersion: =homestead +// ---- From 464ac18a1f451430d1e2e7f1090a2671237e27d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 16:39:51 +0200 Subject: [PATCH 0045/1748] Rename negation_bug.yul to negation_bug.sol --- .../semanticTests/viaYul/{negation_bug.yul => negation_bug.sol} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/semanticTests/viaYul/{negation_bug.yul => negation_bug.sol} (100%) diff --git a/test/libsolidity/semanticTests/viaYul/negation_bug.yul b/test/libsolidity/semanticTests/viaYul/negation_bug.sol similarity index 100% rename from test/libsolidity/semanticTests/viaYul/negation_bug.yul rename to test/libsolidity/semanticTests/viaYul/negation_bug.sol From 60ba3b307fd5e16cd0f68f0533e982a66ce5877b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 17:34:57 +0200 Subject: [PATCH 0046/1748] isolate_tests: Fix typo in script description --- scripts/isolate_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/isolate_tests.py b/scripts/isolate_tests.py index 1e2170e828..4abe6a0bd4 100755 --- a/scripts/isolate_tests.py +++ b/scripts/isolate_tests.py @@ -134,7 +134,7 @@ def extract_and_write(path, language): if __name__ == '__main__': script_description = ( "Reads Solidity, C++ or RST source files and extracts compilable solidity and yul code blocks from them. " - "Can be used to generate test cases to validade code examples. " + "Can be used to generate test cases to validate code examples. " ) parser = ArgumentParser(description=script_description) From fd66f13dc0ca8052eb3bf1dedf5afb6ed8c14399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 19:08:06 +0200 Subject: [PATCH 0047/1748] soltest.sh: Fix typo in a comment --- .circleci/soltest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/soltest.sh b/.circleci/soltest.sh index 4f9bd8a81d..1814b87280 100755 --- a/.circleci/soltest.sh +++ b/.circleci/soltest.sh @@ -46,7 +46,7 @@ source "${REPODIR}/scripts/common.sh" # Test result output directory (CircleCI is reading test results from here) mkdir -p test_results -# in case we run with ASAN enabled, we must increase stck size. +# in case we run with ASAN enabled, we must increase stack size. ulimit -s 16384 get_logfile_basename() { From 8e208f23cba81f965b178a076de2e2f4c144a70d Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 28 Oct 2021 16:25:43 +0200 Subject: [PATCH 0048/1748] Fix assignment of return variables from modifiers. --- Changelog.md | 3 +++ libsolidity/codegen/ir/IRGenerator.cpp | 4 ++-- .../function_modifier_return_reference.sol | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/semanticTests/modifiers/function_modifier_return_reference.sol diff --git a/Changelog.md b/Changelog.md index ff183e22b2..4cfbe6637a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -29,6 +29,9 @@ Bugfixes: * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts. +Important Bugfixes in Experimental Features: + * Yul IR Generator: Changes to function return variables referenced in modifier invocation arguments were not properly forwarded if there was more than one return variable. + ### 0.8.9 (2021-09-29) diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 44cd534ff1..b17b33c03f 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -438,7 +438,7 @@ string IRGenerator::generateModifier( for (size_t i = 0; i < retParamsIn.size(); ++i) { retParams.emplace_back(m_context.newYulVariable()); - assignRetParams += retParams.back() + " := " + retParamsIn[i] + "\n"; + assignRetParams += retParams.at(i) + " := " + retParamsIn.at(i) + "\n"; } t("retParams", joinHumanReadable(retParams)); t("assignRetParams", assignRetParams); @@ -529,7 +529,7 @@ string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const& for (size_t i = 0; i < retParams.size(); ++i) { retParamsIn.emplace_back(m_context.newYulVariable()); - assignRetParams += retParams.back() + " := " + retParamsIn[i] + "\n"; + assignRetParams += retParams.at(i) + " := " + retParamsIn.at(i) + "\n"; } vector params = retParamsIn; for (auto const& varDecl: _function.parameters()) diff --git a/test/libsolidity/semanticTests/modifiers/function_modifier_return_reference.sol b/test/libsolidity/semanticTests/modifiers/function_modifier_return_reference.sol new file mode 100644 index 0000000000..1da6c011d1 --- /dev/null +++ b/test/libsolidity/semanticTests/modifiers/function_modifier_return_reference.sol @@ -0,0 +1,15 @@ +contract C { + modifier m1(uint value) { + _; + } + modifier m2(uint value) { + _; + } + + function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) { + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> 2, 3 From 7683442ce27c083c5f51484ba9322c0678339406 Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Mon, 1 Nov 2021 10:24:08 +0100 Subject: [PATCH 0049/1748] Semantic test for high level call to precompiles. Because of the extcodesize check, the high level call will fail. Even though the low level call can succeed and return data. --- .../precompile_extcodesize_check.sol | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol diff --git a/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol new file mode 100644 index 0000000000..7a9025e26c --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol @@ -0,0 +1,25 @@ +interface Identity { + function selectorAndAppendValue(uint value) external pure returns (uint); +} +contract C { + Identity constant i = Identity(address(0x0004)); + function testHighLevel() external pure returns (bool) { + // Should fail because `extcodesize(4) = 0` + i.selectorAndAppendValue(5); + return true; + } + function testLowLevel() external view returns (uint value) { + (bool success, bytes memory ret) = + address(4).staticcall( + abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5)) + ); + value = abi.decode(ret, (uint)); + } + +} +// ==== +// compileViaYul: also +// EVMVersion: >=constantinople +// ---- +// testHighLevel() -> FAILURE +// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000 From d6c461ed618849fcad037974455d65aa4e09c9e0 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 5 Oct 2021 18:46:49 +0200 Subject: [PATCH 0050/1748] Use side effects of user-defined functions in other optimizer steps. --- libyul/optimiser/ConditionalSimplifier.cpp | 9 +++++- libyul/optimiser/ConditionalSimplifier.h | 14 +++++----- libyul/optimiser/ConditionalUnsimplifier.cpp | 9 +++++- libyul/optimiser/ConditionalUnsimplifier.h | 13 +++++---- libyul/optimiser/DeadCodeEliminator.cpp | 9 ++++-- libyul/optimiser/DeadCodeEliminator.h | 11 ++++++-- libyul/optimiser/Semantics.cpp | 29 ++++++++++++++++---- libyul/optimiser/Semantics.h | 26 ++++++++++++------ 8 files changed, 88 insertions(+), 32 deletions(-) diff --git a/libyul/optimiser/ConditionalSimplifier.cpp b/libyul/optimiser/ConditionalSimplifier.cpp index ea32949ed7..3a2e8aa4e4 100644 --- a/libyul/optimiser/ConditionalSimplifier.cpp +++ b/libyul/optimiser/ConditionalSimplifier.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include using namespace std; @@ -26,6 +27,12 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; +void ConditionalSimplifier::run(OptimiserStepContext& _context, Block& _ast) +{ + ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); + ConditionalSimplifier{_context.dialect, sideEffects.functionSideEffects()}(_ast); +} + void ConditionalSimplifier::operator()(Switch& _switch) { visit(*_switch.expression); @@ -65,7 +72,7 @@ void ConditionalSimplifier::operator()(Block& _block) if ( holds_alternative(*_if.condition) && !_if.body.statements.empty() && - TerminationFinder(m_dialect).controlFlowKind(_if.body.statements.back()) != + TerminationFinder(m_dialect, &m_functionSideEffects).controlFlowKind(_if.body.statements.back()) != TerminationFinder::ControlFlow::FlowOut ) { diff --git a/libyul/optimiser/ConditionalSimplifier.h b/libyul/optimiser/ConditionalSimplifier.h index e41ee579cc..57a6696c4b 100644 --- a/libyul/optimiser/ConditionalSimplifier.h +++ b/libyul/optimiser/ConditionalSimplifier.h @@ -44,7 +44,6 @@ namespace solidity::yul * * Future features: * - allow replacements by "1" - * - take termination of user-defined functions into account * * Works best with SSA form and if dead code removal has run before. * @@ -54,20 +53,21 @@ class ConditionalSimplifier: public ASTModifier { public: static constexpr char const* name{"ConditionalSimplifier"}; - static void run(OptimiserStepContext& _context, Block& _ast) - { - ConditionalSimplifier{_context.dialect}(_ast); - } + static void run(OptimiserStepContext& _context, Block& _ast); using ASTModifier::operator(); void operator()(Switch& _switch) override; void operator()(Block& _block) override; private: - explicit ConditionalSimplifier(Dialect const& _dialect): - m_dialect(_dialect) + explicit ConditionalSimplifier( + Dialect const& _dialect, + std::map const& _sideEffects + ): + m_dialect(_dialect), m_functionSideEffects(_sideEffects) {} Dialect const& m_dialect; + std::map const& m_functionSideEffects; }; } diff --git a/libyul/optimiser/ConditionalUnsimplifier.cpp b/libyul/optimiser/ConditionalUnsimplifier.cpp index f522654d43..752e06918b 100644 --- a/libyul/optimiser/ConditionalUnsimplifier.cpp +++ b/libyul/optimiser/ConditionalUnsimplifier.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include using namespace std; @@ -27,6 +28,12 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; +void ConditionalUnsimplifier::run(OptimiserStepContext& _context, Block& _ast) +{ + ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); + ConditionalUnsimplifier{_context.dialect, sideEffects.functionSideEffects()}(_ast); +} + void ConditionalUnsimplifier::operator()(Switch& _switch) { visit(*_switch.expression); @@ -78,7 +85,7 @@ void ConditionalUnsimplifier::operator()(Block& _block) YulString condition = std::get(*_if.condition).name; if ( holds_alternative(_stmt2) && - TerminationFinder(m_dialect).controlFlowKind(_if.body.statements.back()) != + TerminationFinder(m_dialect, &m_functionSideEffects).controlFlowKind(_if.body.statements.back()) != TerminationFinder::ControlFlow::FlowOut ) { diff --git a/libyul/optimiser/ConditionalUnsimplifier.h b/libyul/optimiser/ConditionalUnsimplifier.h index 975011b957..8025b661b9 100644 --- a/libyul/optimiser/ConditionalUnsimplifier.h +++ b/libyul/optimiser/ConditionalUnsimplifier.h @@ -33,20 +33,21 @@ class ConditionalUnsimplifier: public ASTModifier { public: static constexpr char const* name{"ConditionalUnsimplifier"}; - static void run(OptimiserStepContext& _context, Block& _ast) - { - ConditionalUnsimplifier{_context.dialect}(_ast); - } + static void run(OptimiserStepContext& _context, Block& _ast); using ASTModifier::operator(); void operator()(Switch& _switch) override; void operator()(Block& _block) override; private: - explicit ConditionalUnsimplifier(Dialect const& _dialect): - m_dialect(_dialect) + explicit ConditionalUnsimplifier( + Dialect const& _dialect, + std::map const& _sideEffects + ): + m_dialect(_dialect), m_functionSideEffects(_sideEffects) {} Dialect const& m_dialect; + std::map const& m_functionSideEffects; }; } diff --git a/libyul/optimiser/DeadCodeEliminator.cpp b/libyul/optimiser/DeadCodeEliminator.cpp index 6a279487f8..ad127a9108 100644 --- a/libyul/optimiser/DeadCodeEliminator.cpp +++ b/libyul/optimiser/DeadCodeEliminator.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,11 @@ using namespace solidity::yul; void DeadCodeEliminator::run(OptimiserStepContext& _context, Block& _ast) { - DeadCodeEliminator{_context.dialect}(_ast); + ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); + DeadCodeEliminator{ + _context.dialect, + sideEffects.functionSideEffects() + }(_ast); } void DeadCodeEliminator::operator()(ForLoop& _for) @@ -49,7 +54,7 @@ void DeadCodeEliminator::operator()(Block& _block) { TerminationFinder::ControlFlow controlFlowChange; size_t index; - tie(controlFlowChange, index) = TerminationFinder{m_dialect}.firstUnconditionalControlFlowChange(_block.statements); + tie(controlFlowChange, index) = TerminationFinder{m_dialect, &m_functionSideEffects}.firstUnconditionalControlFlowChange(_block.statements); // Erase everything after the terminating statement that is not a function definition. if (controlFlowChange != TerminationFinder::ControlFlow::FlowOut && index != std::numeric_limits::max()) diff --git a/libyul/optimiser/DeadCodeEliminator.h b/libyul/optimiser/DeadCodeEliminator.h index d47bf86ea8..98202fc943 100644 --- a/libyul/optimiser/DeadCodeEliminator.h +++ b/libyul/optimiser/DeadCodeEliminator.h @@ -31,12 +31,15 @@ namespace solidity::yul { struct Dialect; struct OptimiserStepContext; +struct ControlFlowSideEffects; /** * Optimisation stage that removes unreachable code * * Unreachable code is any code within a block which is preceded by a - * leave, return, invalid, break, continue, selfdestruct or revert. + * leave, return, invalid, break, continue, selfdestruct or revert or + * a call to a user-defined function that never returns (either due to + * recursion or a call to return / revert / stop). * * Function definitions are retained as they might be called by earlier * code and thus are considered reachable. @@ -57,9 +60,13 @@ class DeadCodeEliminator: public ASTModifier void operator()(Block& _block) override; private: - DeadCodeEliminator(Dialect const& _dialect): m_dialect(_dialect) {} + DeadCodeEliminator( + Dialect const& _dialect, + std::map const& _sideEffects + ): m_dialect(_dialect), m_functionSideEffects(_sideEffects) {} Dialect const& m_dialect; + std::map const& m_functionSideEffects; }; } diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp index bdd08710eb..12349394a0 100644 --- a/libyul/optimiser/Semantics.cpp +++ b/libyul/optimiser/Semantics.cpp @@ -182,8 +182,19 @@ pair TerminationFinder::firstUncondition TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement const& _statement) { if ( + holds_alternative(_statement) && + std::get(_statement).value && + containsNonContinuingFunctionCall(*std::get(_statement).value) + ) + return ControlFlow::Terminate; + else if ( + holds_alternative(_statement) && + containsNonContinuingFunctionCall(*std::get(_statement).value) + ) + return ControlFlow::Terminate; + else if ( holds_alternative(_statement) && - isTerminatingBuiltin(std::get(_statement)) + containsNonContinuingFunctionCall(std::get(_statement).expression) ) return ControlFlow::Terminate; else if (holds_alternative(_statement)) @@ -196,10 +207,18 @@ TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement cons return ControlFlow::FlowOut; } -bool TerminationFinder::isTerminatingBuiltin(ExpressionStatement const& _exprStmnt) +bool TerminationFinder::containsNonContinuingFunctionCall(Expression const& _expr) { - if (holds_alternative(_exprStmnt.expression)) - if (auto instruction = toEVMInstruction(m_dialect, std::get(_exprStmnt.expression).functionName.name)) - return evmasm::SemanticInformation::terminatesControlFlow(*instruction); + if (auto functionCall = std::get_if(&_expr)) + { + for (auto const& arg: functionCall->arguments) + if (containsNonContinuingFunctionCall(arg)) + return true; + + if (auto builtin = m_dialect.builtin(functionCall->functionName.name)) + return !builtin->controlFlowSideEffects.canContinue; + else if (m_functionSideEffects && m_functionSideEffects->count(functionCall->functionName.name)) + return !m_functionSideEffects->at(functionCall->functionName.name).canContinue; + } return false; } diff --git a/libyul/optimiser/Semantics.h b/libyul/optimiser/Semantics.h index 75ea401515..32b9c9b582 100644 --- a/libyul/optimiser/Semantics.h +++ b/libyul/optimiser/Semantics.h @@ -205,22 +205,31 @@ class MovableChecker: public SideEffectsCollector std::set m_variableReferences; }; +struct ControlFlowSideEffects; /** * Helper class to find "irregular" control flow. - * This includes termination, break and continue. + * This includes termination, break, continue and leave. + * In general, it is applied only to "simple" statements. The control-flow + * of loops, switches and if statements is always "FlowOut" with the assumption + * that the caller will descend into them. */ class TerminationFinder { public: - // TODO check all uses of TerminationFinder! + /// "Terminate" here means that there is no continuing control-flow. + /// If this is applied to a function that can revert or stop, but can also + /// exit regularly, the property is set to "FlowOut". enum class ControlFlow { FlowOut, Break, Continue, Terminate, Leave }; - TerminationFinder(Dialect const& _dialect): m_dialect(_dialect) {} + TerminationFinder( + Dialect const& _dialect, + std::map const* _functionSideEffects = nullptr + ): m_dialect(_dialect), m_functionSideEffects(_functionSideEffects) {} /// @returns the index of the first statement in the provided sequence /// that is an unconditional ``break``, ``continue``, ``leave`` or a - /// call to a terminating builtin function. + /// call to a terminating function. /// If control flow can continue at the end of the list, /// returns `FlowOut` and ``size_t(-1)``. /// The function might return ``FlowOut`` even though control @@ -233,13 +242,14 @@ class TerminationFinder /// This function could return FlowOut even if control flow never continues. ControlFlow controlFlowKind(Statement const& _statement); - /// @returns true if the expression statement is a direct - /// call to a builtin terminating function like - /// ``stop``, ``revert`` or ``return``. - bool isTerminatingBuiltin(ExpressionStatement const& _exprStmnt); + /// @returns true if the expression contains a + /// call to a terminating function, i.e. a function that does not have + /// a regular "flow out" control-flow (it might also be recursive). + bool containsNonContinuingFunctionCall(Expression const& _expr); private: Dialect const& m_dialect; + std::map const* m_functionSideEffects; }; } From 3996d0a34363d1b8b489b40aac204ec1adf11cb4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 25 Oct 2021 16:54:29 +0200 Subject: [PATCH 0051/1748] Update tests. --- .../dead_code_user_functions.yul | 44 +++++++++++++++++++ .../function_after_revert.yul | 6 +-- .../fullSuite/name_cleaner_reserved.yul | 8 ++-- ...nusedFunctionParameterPruner_recursion.yul | 16 ++++--- 4 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/deadCodeEliminator/dead_code_user_functions.yul diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/dead_code_user_functions.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/dead_code_user_functions.yul new file mode 100644 index 0000000000..00293d71d1 --- /dev/null +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/dead_code_user_functions.yul @@ -0,0 +1,44 @@ +{ + switch calldataload(0) + case 0 { + recursive() + sstore(0, 1) + } + case 1 { + terminating() + sstore(0, 7) + } + case 2 { + reverting() + sstore(0, 7) + } + + + function recursive() + { + recursive() + } + function terminating() + { + return(0, 0) + } + function reverting() + { + revert(0, 0) + } +} +// ---- +// step: deadCodeEliminator +// +// { +// switch calldataload(0) +// case 0 { recursive() } +// case 1 { terminating() } +// case 2 { reverting() } +// function recursive() +// { recursive() } +// function terminating() +// { return(0, 0) } +// function reverting() +// { revert(0, 0) } +// } diff --git a/test/libyul/yulOptimizerTests/deadCodeEliminator/function_after_revert.yul b/test/libyul/yulOptimizerTests/deadCodeEliminator/function_after_revert.yul index d5df28fb09..a75636b760 100644 --- a/test/libyul/yulOptimizerTests/deadCodeEliminator/function_after_revert.yul +++ b/test/libyul/yulOptimizerTests/deadCodeEliminator/function_after_revert.yul @@ -5,9 +5,7 @@ function fun() { - return(1, 1) - - pop(sub(10, 5)) + sstore(0, 1) } pop(add(1, 1)) @@ -19,5 +17,5 @@ // fun() // revert(0, 0) // function fun() -// { return(1, 1) } +// { sstore(0, 1) } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/name_cleaner_reserved.yul b/test/libyul/yulOptimizerTests/fullSuite/name_cleaner_reserved.yul index 576f5abb90..851ccbce2a 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/name_cleaner_reserved.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/name_cleaner_reserved.yul @@ -1,11 +1,11 @@ { // This function name can be shortened, the other cannot. function nonmstore_(x) { - nonmstore_(x) + if calldataload(0) { nonmstore_(x) } sstore(10, calldataload(2)) } function mstore_(x) -> y { - let t3_3_ := mstore_(x) + if calldataload(0) { let t3_3_ := mstore_(x) } y := 8 sstore(y, calldataload(y)) } @@ -22,12 +22,12 @@ // } // function nonmstore(x) // { -// nonmstore(x) +// if calldataload(0) { nonmstore(x) } // sstore(10, calldataload(2)) // } // function mstore_(x) -> y // { -// pop(mstore_(x)) +// if calldataload(0) { pop(mstore_(x)) } // y := 8 // sstore(y, calldataload(y)) // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_recursion.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_recursion.yul index 69b4517eb3..c3b75e84ee 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_recursion.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_recursion.yul @@ -5,7 +5,9 @@ sstore(1, l) function f(a, b, c) -> x, y, z { - x, y, z := f(1, 2, 3) + if calldataload(0) { + x, y, z := f(1, 2, 3) + } x := add(x, 1) } } @@ -21,9 +23,13 @@ // } // function f() -> x, y, z // { -// let x_1, y_1, z_1 := f() -// y := y_1 -// z := z_1 -// x := add(x_1, 1) +// if calldataload(0) +// { +// let x_1, y_1, z_1 := f() +// x := x_1 +// y := y_1 +// z := z_1 +// } +// x := add(x, 1) // } // } From 7f7c5ca171b33d1bcbbebfdbc5c887509d60fdf9 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 2 Nov 2021 11:50:37 +0100 Subject: [PATCH 0052/1748] New tests. --- .../side_effects_of_functions.yul | 38 +++++++++++++++++++ .../side_effects_of_functions.yul | 38 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 test/libyul/yulOptimizerTests/conditionalSimplifier/side_effects_of_functions.yul create mode 100644 test/libyul/yulOptimizerTests/conditionalUnsimplifier/side_effects_of_functions.yul diff --git a/test/libyul/yulOptimizerTests/conditionalSimplifier/side_effects_of_functions.yul b/test/libyul/yulOptimizerTests/conditionalSimplifier/side_effects_of_functions.yul new file mode 100644 index 0000000000..c448fdf023 --- /dev/null +++ b/test/libyul/yulOptimizerTests/conditionalSimplifier/side_effects_of_functions.yul @@ -0,0 +1,38 @@ +{ + function recursive() { recursive() } + function terminating() { stop() } + function maybeReverting() { if calldataload(0) { revert(0, 0) } } + + let a := calldataload(7) + if a { recursive() } + + a := calldataload(a) + if a { maybeReverting() } + + a := calldataload(a) + if a { terminating() } + + sstore(0, a) +} +// ---- +// step: conditionalSimplifier +// +// { +// function recursive() +// { recursive() } +// function terminating() +// { stop() } +// function maybeReverting() +// { +// if calldataload(0) { revert(0, 0) } +// } +// let a := calldataload(7) +// if a { recursive() } +// a := 0 +// a := calldataload(a) +// if a { maybeReverting() } +// a := calldataload(a) +// if a { terminating() } +// a := 0 +// sstore(0, a) +// } diff --git a/test/libyul/yulOptimizerTests/conditionalUnsimplifier/side_effects_of_functions.yul b/test/libyul/yulOptimizerTests/conditionalUnsimplifier/side_effects_of_functions.yul new file mode 100644 index 0000000000..25e17d75ac --- /dev/null +++ b/test/libyul/yulOptimizerTests/conditionalUnsimplifier/side_effects_of_functions.yul @@ -0,0 +1,38 @@ +{ + function recursive() { recursive() } + function terminating() { stop() } + function maybeReverting() { if calldataload(0) { revert(0, 0) } } + + let a := calldataload(7) + if a { recursive() } + a := 0 + + a := calldataload(a) + if a { maybeReverting() } + + a := calldataload(a) + if a { terminating() } + a := 0 + + sstore(0, a) +} +// ---- +// step: conditionalUnsimplifier +// +// { +// function recursive() +// { recursive() } +// function terminating() +// { stop() } +// function maybeReverting() +// { +// if calldataload(0) { revert(0, 0) } +// } +// let a := calldataload(7) +// if a { recursive() } +// a := calldataload(a) +// if a { maybeReverting() } +// a := calldataload(a) +// if a { terminating() } +// sstore(0, a) +// } From be6fb5f3d658f914a60dc99016165ced956a6519 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 2 Nov 2021 11:54:10 +0100 Subject: [PATCH 0053/1748] Changelog entry. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 4cfbe6637a..c724693eeb 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Compiler Features: * SMTChecker: Report contract invariants and reentrancy properties. This can be enabled via the CLI option ``--model-checker-invariants`` or the Standard JSON option ``settings.modelChecker.invariants``. * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. * Standard JSON: Add ``settings.debug.debugInfo`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. + * Yul Optimizer: Take control-flow side-effects of user-defined functions into account in various optimizer steps. Bugfixes: From 93c1fe68789ae23c610570c70685d0c6a9aa8a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 11 Oct 2021 13:03:51 +0200 Subject: [PATCH 0054/1748] Treat --help, --license and --version as separate input modes --- solc/CommandLineInterface.cpp | 64 +++++++++++++++++++++++---- solc/CommandLineInterface.h | 2 + solc/CommandLineParser.cpp | 69 +++++++++++------------------- solc/CommandLineParser.h | 28 ++++-------- test/solc/CommandLineInterface.cpp | 39 ++++++++++++++++- test/solc/CommandLineParser.cpp | 62 +++++++++++++-------------- 6 files changed, 159 insertions(+), 105 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 6c24b7742b..e86381bf3f 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -23,6 +23,7 @@ */ #include +#include "license.h" #include "solidity/BuildInfo.h" #include @@ -405,6 +406,13 @@ bool CommandLineInterface::readInputFiles() { solAssert(!m_standardJsonInput.has_value(), ""); + if ( + m_options.input.mode == InputMode::Help || + m_options.input.mode == InputMode::License || + m_options.input.mode == InputMode::Version + ) + return true; + m_fileReader.setBasePath(m_options.input.basePath); if (m_fileReader.basePath() != "") @@ -573,8 +581,18 @@ void CommandLineInterface::createJson(string const& _fileName, string const& _js bool CommandLineInterface::parseArguments(int _argc, char const* const* _argv) { - CommandLineParser parser(sout(/* _markAsUsed */ false), serr(/* _markAsUsed */ false)); - bool success = parser.parse(_argc, _argv, isatty(fileno(stdin))); + CommandLineParser parser(serr(/* _markAsUsed */ false)); + + if (isatty(fileno(stdin)) && _argc == 1) + { + // If the terminal is taking input from the user, provide more user-friendly output. + CommandLineParser::printHelp(sout()); + + // In this case we want to exit with an error but not display any error message. + return false; + } + + bool success = parser.parse(_argc, _argv); if (!success) return false; m_hasOutput = m_hasOutput || parser.hasOutput(); @@ -587,6 +605,15 @@ bool CommandLineInterface::processInput() { switch (m_options.input.mode) { + case InputMode::Help: + CommandLineParser::printHelp(sout()); + return false; + case InputMode::License: + printLicense(); + return true; + case InputMode::Version: + printVersion(); + return true; case InputMode::StandardJson: { solAssert(m_standardJsonInput.has_value(), ""); @@ -611,6 +638,19 @@ bool CommandLineInterface::processInput() return false; } +void CommandLineInterface::printVersion() +{ + sout() << "solc, the solidity compiler commandline interface" << endl; + sout() << "Version: " << solidity::frontend::VersionString << endl; +} + +void CommandLineInterface::printLicense() +{ + sout() << otherLicenses << endl; + // This is a static variable generated by cmake from LICENSE.txt + sout() << licenseText << endl; +} + bool CommandLineInterface::compile() { solAssert(m_options.input.mode == InputMode::Compiler || m_options.input.mode == InputMode::CompilerWithASTImport, ""); @@ -845,16 +885,24 @@ void CommandLineInterface::handleAst() bool CommandLineInterface::actOnInput() { - if (m_options.input.mode == InputMode::StandardJson || m_options.input.mode == InputMode::Assembler) + switch (m_options.input.mode) + { + case InputMode::Help: + case InputMode::License: + case InputMode::Version: + case InputMode::StandardJson: + case InputMode::Assembler: // Already done in "processInput" phase. - return true; - else if (m_options.input.mode == InputMode::Linker) + break; + case InputMode::Linker: writeLinkedFiles(); - else - { - solAssert(m_options.input.mode == InputMode::Compiler || m_options.input.mode == InputMode::CompilerWithASTImport, ""); + break; + case InputMode::Compiler: + case InputMode::CompilerWithASTImport: outputCompilationResults(); + break; } + return !m_outputFailed; } diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index 1ca40568cc..e99ed1c07e 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -66,6 +66,8 @@ class CommandLineInterface std::optional const& standardJsonInput() const { return m_standardJsonInput; } private: + void printVersion(); + void printLicense(); bool compile(); bool link(); void writeLinkedFiles(); diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 22d92d4630..c3448ff8fa 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -16,8 +16,6 @@ */ // SPDX-License-Identifier: GPL-3.0 -#include "license.h" - #include #include #include @@ -36,19 +34,12 @@ namespace po = boost::program_options; namespace solidity::frontend { -ostream& CommandLineParser::sout() -{ - m_hasOutput = true; - return m_sout; -} - ostream& CommandLineParser::serr() { m_hasOutput = true; return m_serr; } -#define cout #define cerr static string const g_strAllowPaths = "allow-paths"; @@ -147,26 +138,6 @@ static map const g_inputModeName = { {InputMode::Linker, "linker"}, }; -void CommandLineParser::printVersionAndExit() -{ - sout() << - "solc, the solidity compiler commandline interface" << - endl << - "Version: " << - solidity::frontend::VersionString << - endl; - exit(EXIT_SUCCESS); -} - -void CommandLineParser::printLicenseAndExit() -{ - sout() << otherLicenses << endl; - // This is a static variable generated by cmake from LICENSE.txt - sout() << licenseText << endl; - exit(EXIT_SUCCESS); -} - - bool CommandLineParser::checkMutuallyExclusive(vector const& _optionNames) { if (countEnabledOptions(_optionNames) > 1) @@ -297,11 +268,11 @@ OptimiserSettings CommandLineOptions::optimiserSettings() const return settings; } -bool CommandLineParser::parse(int _argc, char const* const* _argv, bool _interactiveTerminal) +bool CommandLineParser::parse(int _argc, char const* const* _argv) { m_hasOutput = false; - if (!parseArgs(_argc, _argv, _interactiveTerminal)) + if (!parseArgs(_argc, _argv)) return false; return processArgs(); @@ -482,6 +453,10 @@ bool CommandLineParser::parseOutputSelection() switch (_mode) { + case InputMode::Help: + case InputMode::License: + case InputMode::Version: + solAssert(false); case InputMode::Compiler: case InputMode::CompilerWithASTImport: return contains(compilerModeOutputs, _outputName); @@ -847,7 +822,7 @@ po::positional_options_description CommandLineParser::positionalOptionsDescripti return filesPositions; } -bool CommandLineParser::parseArgs(int _argc, char const* const* _argv, bool _interactiveTerminal) +bool CommandLineParser::parseArgs(int _argc, char const* const* _argv) { po::options_description allOptions = optionsDescription(); po::positional_options_description filesPositions = positionalOptionsDescription(); @@ -866,18 +841,6 @@ bool CommandLineParser::parseArgs(int _argc, char const* const* _argv, bool _int return false; } - if (m_args.count(g_strHelp) || (_interactiveTerminal && _argc == 1)) - { - sout() << allOptions; - return false; - } - - if (m_args.count(g_strVersion)) - printVersionAndExit(); - - if (m_args.count(g_strLicense)) - printLicenseAndExit(); - po::notify(m_args); return true; @@ -886,6 +849,9 @@ bool CommandLineParser::parseArgs(int _argc, char const* const* _argv, bool _int bool CommandLineParser::processArgs() { if (!checkMutuallyExclusive({ + g_strHelp, + g_strLicense, + g_strVersion, g_strStandardJSON, g_strLink, g_strAssemble, @@ -895,7 +861,13 @@ bool CommandLineParser::processArgs() })) return false; - if (m_args.count(g_strStandardJSON) > 0) + if (m_args.count(g_strHelp) > 0) + m_options.input.mode = InputMode::Help; + else if (m_args.count(g_strLicense) > 0) + m_options.input.mode = InputMode::License; + else if (m_args.count(g_strVersion) > 0) + m_options.input.mode = InputMode::Version; + else if (m_args.count(g_strStandardJSON) > 0) m_options.input.mode = InputMode::StandardJson; else if (m_args.count(g_strAssemble) > 0 || m_args.count(g_strStrictAssembly) > 0 || m_args.count(g_strYul) > 0) m_options.input.mode = InputMode::Assembler; @@ -906,6 +878,13 @@ bool CommandLineParser::processArgs() else m_options.input.mode = InputMode::Compiler; + if ( + m_options.input.mode == InputMode::Help || + m_options.input.mode == InputMode::License || + m_options.input.mode == InputMode::Version + ) + return true; + map> validOptionInputModeCombinations = { // TODO: This should eventually contain all options. {g_strErrorRecovery, {InputMode::Compiler, InputMode::CompilerWithASTImport}}, diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index ad525ea3b2..27a64c7b94 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -48,6 +48,9 @@ namespace solidity::frontend enum class InputMode { + Help, + License, + Version, Compiler, CompilerWithASTImport, StandardJson, @@ -230,34 +233,28 @@ struct CommandLineOptions /// Parses the command-line arguments and produces a filled-out CommandLineOptions structure. /// Validates provided values and prints error messages in case of errors. -/// -/// The class is also responsible for handling options that only result in printing informational -/// text, without the need to invoke the compiler - printing usage banner, version or license. class CommandLineParser { public: - explicit CommandLineParser(std::ostream& _sout, std::ostream& _serr): - m_sout(_sout), + explicit CommandLineParser(std::ostream& _serr): m_serr(_serr) {} /// Parses the command-line arguments and fills out the internal CommandLineOptions structure. - /// Performs validation and prints error messages. If requested, prints usage banner, version - /// or license. - /// @param interactiveTerminal specifies whether the terminal is taking input from the user. - /// This is used to determine whether to provide more user-friendly output in some situations. - /// E.g. whether to print help text when no arguments are provided. + /// Performs validation and prints error messages. /// @return true if there were no validation errors when parsing options and the /// CommandLineOptions structure has been fully initialized. false if there were errors - in /// this case CommandLineOptions may be only partially filled out. May also return false if /// there is not further processing necessary and the program should just exit. - bool parse(int _argc, char const* const* _argv, bool _interactiveTerminal); + bool parse(int _argc, char const* const* _argv); CommandLineOptions const& options() const { return m_options; } /// Returns true if the parser has written anything to any of its output streams. bool hasOutput() const { return m_hasOutput; } + static void printHelp(std::ostream& _out) { _out << optionsDescription(); } + private: /// @returns a specification of all named command-line options accepted by the compiler. /// The object can be used to parse command-line arguments or to generate the help screen. @@ -270,7 +267,7 @@ class CommandLineParser /// Uses boost::program_options to parse the command-line arguments and leaves the result in @a m_args. /// Also handles the arguments that result in information being printed followed by immediate exit. /// @returns false if parsing fails due to syntactical errors or the arguments not matching the description. - bool parseArgs(int _argc, char const* const* _argv, bool _interactiveTerminal); + bool parseArgs(int _argc, char const* const* _argv); /// Validates parsed arguments stored in @a m_args and fills out the internal CommandLineOptions /// structure. @@ -294,20 +291,13 @@ class CommandLineParser bool parseOutputSelection(); bool checkMutuallyExclusive(std::vector const& _optionNames); - [[noreturn]] void printVersionAndExit(); - [[noreturn]] void printLicenseAndExit(); size_t countEnabledOptions(std::vector const& _optionNames) const; static std::string joinOptionNames(std::vector const& _optionNames, std::string _separator = ", "); - /// Returns the stream that should receive normal output. Sets m_hasOutput to true if the - /// stream has ever been used. - std::ostream& sout(); - /// Returns the stream that should receive error output. Sets m_hasOutput to true if the /// stream has ever been used. std::ostream& serr(); - std::ostream& m_sout; std::ostream& m_serr; bool m_hasOutput = false; diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 3d1fce7d2b..739213e8f2 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -29,6 +29,8 @@ #include +#include + #include #include @@ -110,9 +112,42 @@ namespace solidity::frontend::test BOOST_AUTO_TEST_SUITE(CommandLineInterfaceTest) +BOOST_AUTO_TEST_CASE(help) +{ + OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--help"}, "", /* _processInput */ true); + + BOOST_TEST(!result.success); + BOOST_TEST(boost::starts_with(result.stdoutContent, "solc, the Solidity commandline compiler.")); + BOOST_TEST(result.stderrContent == ""); + BOOST_TEST(result.options.input.mode == InputMode::Help); +} + +BOOST_AUTO_TEST_CASE(license) +{ + OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--license"}, "", /* _processInput */ true); + + BOOST_TEST(result.success); + BOOST_TEST(boost::starts_with(result.stdoutContent, "Most of the code is licensed under GPLv3")); + BOOST_TEST(result.stderrContent == ""); + BOOST_TEST(result.options.input.mode == InputMode::License); +} + +BOOST_AUTO_TEST_CASE(version) +{ + OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--version"}, "", /* _processInput */ true); + + BOOST_TEST(result.success); + BOOST_TEST(boost::ends_with(result.stdoutContent, "Version: " + solidity::frontend::VersionString + "\n")); + BOOST_TEST(result.stderrContent == ""); + BOOST_TEST(result.options.input.mode == InputMode::Version); +} + BOOST_AUTO_TEST_CASE(multiple_input_modes) { - array inputModeOptions = { + array inputModeOptions = { + "--help", + "--license", + "--version", "--standard-json", "--link", "--assemble", @@ -122,7 +157,7 @@ BOOST_AUTO_TEST_CASE(multiple_input_modes) }; string expectedMessage = "The following options are mutually exclusive: " - "--standard-json, --link, --assemble, --strict-assembly, --yul, --import-ast. " + "--help, --license, --version, --standard-json, --link, --assemble, --strict-assembly, --yul, --import-ast. " "Select at most one.\n"; for (string const& mode1: inputModeOptions) diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 663bf022c6..a9ba08d817 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -30,8 +30,6 @@ #include #include -#include - #include #include #include @@ -48,16 +46,12 @@ using namespace solidity::yul; namespace { -optional parseCommandLine(vector const& _commandLine, ostream& _stdout, ostream& _stderr) +optional parseCommandLine(vector const& _commandLine, ostream& _stderr) { vector argv = test::makeArgv(_commandLine); - CommandLineParser cliParser(_stdout, _stderr); - bool success = cliParser.parse( - static_cast(_commandLine.size()), - argv.data(), - false // interactiveTerminal - ); + CommandLineParser cliParser(_stderr); + bool success = cliParser.parse(static_cast(_commandLine.size()), argv.data()); if (!success) return nullopt; @@ -81,24 +75,34 @@ BOOST_AUTO_TEST_CASE(no_options) expectedOptions.modelChecker.initialize = true; expectedOptions.modelChecker.settings = {}; - stringstream sout, serr; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); + stringstream serr; + optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(sout.str() == ""); BOOST_TEST(serr.str() == ""); BOOST_REQUIRE(parsedOptions.has_value()); BOOST_TEST(parsedOptions.value() == expectedOptions); } -BOOST_AUTO_TEST_CASE(help) +BOOST_AUTO_TEST_CASE(help_license_version) { - stringstream sout, serr; - optional parsedOptions = parseCommandLine({"solc", "--help"}, sout, serr); + map expectedModePerOption = { + {"--help", InputMode::Help}, + {"--license", InputMode::License}, + {"--version", InputMode::Version}, + }; - BOOST_TEST(serr.str() == ""); - BOOST_TEST(boost::starts_with(sout.str(), "solc, the Solidity commandline compiler.")); - BOOST_TEST(sout.str().find("Usage: solc [options] [input_file...]") != string::npos); - BOOST_TEST(!parsedOptions.has_value()); + for (auto const& [option, expectedMode]: expectedModePerOption) + { + stringstream serr; + optional parsedOptions = parseCommandLine({"solc", option}, serr); + + CommandLineOptions expectedOptions; + expectedOptions.input.mode = expectedMode; + + BOOST_TEST(serr.str() == ""); + BOOST_REQUIRE(parsedOptions.has_value()); + BOOST_TEST(parsedOptions.value() == expectedOptions); + } } BOOST_AUTO_TEST_CASE(cli_mode_options) @@ -220,10 +224,9 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) 5, }; - stringstream sout, serr; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); + stringstream serr; + optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(sout.str() == ""); BOOST_TEST(serr.str() == ""); BOOST_REQUIRE(parsedOptions.has_value()); BOOST_TEST(parsedOptions.value() == expectedOptions); @@ -337,10 +340,9 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) expectedOptions.optimizer.expectedExecutionsPerDeployment = 1000; } - stringstream sout, serr; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); + stringstream serr; + optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(sout.str() == ""); BOOST_TEST(serr.str() == "Warning: Yul is still experimental. Please use the output with care.\n"); BOOST_REQUIRE(parsedOptions.has_value()); BOOST_TEST(parsedOptions.value() == expectedOptions); @@ -406,10 +408,9 @@ BOOST_AUTO_TEST_CASE(standard_json_mode_options) expectedOptions.compiler.combinedJsonRequests->abi = true; expectedOptions.compiler.combinedJsonRequests->binary = true; - stringstream sout, serr; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); + stringstream serr; + optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(sout.str() == ""); BOOST_TEST(serr.str() == ""); BOOST_REQUIRE(parsedOptions.has_value()); BOOST_TEST(parsedOptions.value() == expectedOptions); @@ -426,11 +427,10 @@ BOOST_AUTO_TEST_CASE(invalid_options_input_modes_combinations) for (auto const& [optionName, inputModes]: invalidOptionInputModeCombinations) for (string const& inputMode: inputModes) { - stringstream sout, serr; + stringstream serr; vector commandLine = {"solc", optionName, "file", inputMode}; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); + optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(sout.str() == ""); BOOST_TEST(serr.str() == "The following options are not supported in the current input mode: " + optionName + "\n"); BOOST_REQUIRE(!parsedOptions.has_value()); } From a1c9c1e2b5bbe87e70a7179353b305c80fba34eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 11 Oct 2021 13:17:01 +0200 Subject: [PATCH 0055/1748] CommandLineInterface: Merge processInput() and actOnInput() - The distinction between them is not as clear-cut as it should be. For example processInput() prints output in assembly mode. --- solc/CommandLineInterface.cpp | 47 +++++++++++------------------------ solc/CommandLineInterface.h | 5 +--- solc/main.cpp | 3 +-- test/solc/Common.cpp | 6 ++++- 4 files changed, 21 insertions(+), 40 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index e86381bf3f..1358dd484c 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -610,10 +610,10 @@ bool CommandLineInterface::processInput() return false; case InputMode::License: printLicense(); - return true; + break; case InputMode::Version: printVersion(); - return true; + break; case InputMode::StandardJson: { solAssert(m_standardJsonInput.has_value(), ""); @@ -621,21 +621,25 @@ bool CommandLineInterface::processInput() StandardCompiler compiler(m_fileReader.reader(), m_options.formatting.json); sout() << compiler.compile(move(m_standardJsonInput.value())) << endl; m_standardJsonInput.reset(); - return true; + break; } case InputMode::Assembler: - { - return assemble(m_options.assembly.inputLanguage, m_options.assembly.targetMachine); - } + if (!assemble(m_options.assembly.inputLanguage, m_options.assembly.targetMachine)) + return false; + break; case InputMode::Linker: - return link(); + if (!link()) + return false; + writeLinkedFiles(); + break; case InputMode::Compiler: case InputMode::CompilerWithASTImport: - return compile(); + if (!compile()) + return false; + outputCompilationResults(); } - solAssert(false, ""); - return false; + return !m_outputFailed; } void CommandLineInterface::printVersion() @@ -883,29 +887,6 @@ void CommandLineInterface::handleAst() } } -bool CommandLineInterface::actOnInput() -{ - switch (m_options.input.mode) - { - case InputMode::Help: - case InputMode::License: - case InputMode::Version: - case InputMode::StandardJson: - case InputMode::Assembler: - // Already done in "processInput" phase. - break; - case InputMode::Linker: - writeLinkedFiles(); - break; - case InputMode::Compiler: - case InputMode::CompilerWithASTImport: - outputCompilationResults(); - break; - } - - return !m_outputFailed; -} - bool CommandLineInterface::link() { solAssert(m_options.input.mode == InputMode::Linker, ""); diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index e99ed1c07e..ee50574682 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -55,11 +55,8 @@ class CommandLineInterface bool parseArguments(int _argc, char const* const* _argv); /// Read the content of all input files and initialize the file reader. bool readInputFiles(); - /// Parse the files and create source code objects + /// Parse the files, create source code objects, print the output. bool processInput(); - /// Perform actions on the input depending on provided compiler arguments - /// @returns true on success. - bool actOnInput(); CommandLineOptions const& options() const { return m_options; } FileReader const& fileReader() const { return m_fileReader; } diff --git a/solc/main.cpp b/solc/main.cpp index 1299e25644..874ee13ca8 100644 --- a/solc/main.cpp +++ b/solc/main.cpp @@ -65,8 +65,7 @@ int main(int argc, char** argv) bool success = cli.parseArguments(argc, argv) && cli.readInputFiles() && - cli.processInput() && - cli.actOnInput(); + cli.processInput(); return success ? 0 : 1; } diff --git a/test/solc/Common.cpp b/test/solc/Common.cpp index 28263e21e8..8e40c1af63 100644 --- a/test/solc/Common.cpp +++ b/test/solc/Common.cpp @@ -70,6 +70,10 @@ string test::stripPreReleaseWarning(string const& _stderrContent) R"(Warning( \(3805\))?: This is a pre-release compiler version, please do not use it in production\.\n)" R"((\n)?)" }; + static regex const noOutputRegex{ + R"(Compiler run successful, no output requested\.\n)" + }; - return regex_replace(_stderrContent, preReleaseWarningRegex, ""); + string output = regex_replace(_stderrContent, preReleaseWarningRegex, ""); + return regex_replace(move(output), noOutputRegex, ""); } From 0417db0f6a8474468a74515edddcf6d27c5ba977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 11 Oct 2021 13:30:08 +0200 Subject: [PATCH 0056/1748] Don't return an error from --help --- solc/CommandLineInterface.cpp | 2 +- test/solc/CommandLineInterface.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 1358dd484c..9d22799106 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -607,7 +607,7 @@ bool CommandLineInterface::processInput() { case InputMode::Help: CommandLineParser::printHelp(sout()); - return false; + break; case InputMode::License: printLicense(); break; diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 739213e8f2..0269ec462f 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -116,7 +116,7 @@ BOOST_AUTO_TEST_CASE(help) { OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--help"}, "", /* _processInput */ true); - BOOST_TEST(!result.success); + BOOST_TEST(result.success); BOOST_TEST(boost::starts_with(result.stdoutContent, "solc, the Solidity commandline compiler.")); BOOST_TEST(result.stderrContent == ""); BOOST_TEST(result.options.input.mode == InputMode::Help); From 285528f407990112c5f52a3dc3c15d819b551eb4 Mon Sep 17 00:00:00 2001 From: Derek Brans Date: Tue, 2 Nov 2021 20:27:32 -0500 Subject: [PATCH 0057/1748] Added the BigSur 11.6 in the supported os list --- scripts/install_deps.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh index 6a9c12f3f7..7540c8bdf9 100755 --- a/scripts/install_deps.sh +++ b/scripts/install_deps.sh @@ -93,8 +93,8 @@ case $(uname -s) in 10.15) echo "Installing solidity dependencies on macOS 10.15 Catalina." ;; - 11.0 | 11.1 | 11.2 | 11.3 | 11.4 | 11.5) - echo "Installing solidity dependencies on macOS 11.0 / 11.1 / 11.2 / 11.3 / 11.4 / 11.5 Big Sur." + 11.0 | 11.1 | 11.2 | 11.3 | 11.4 | 11.5 | 11.6) + echo "Installing solidity dependencies on macOS 11.0 / 11.1 / 11.2 / 11.3 / 11.4 / 11.5 / 11.6 Big Sur." ;; *) echo "Unsupported macOS version." From e40cf92b1d34120506c648a7abc1db7734d65f4c Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 20 Oct 2021 16:21:34 +0200 Subject: [PATCH 0058/1748] [SMTChecker] Merge all entry points for a target --- libsolidity/formal/CHC.cpp | 27 ++++++++++--------- libsolidity/formal/CHC.h | 4 ++- .../model_checker_invariants_all/err | 1 - .../err | 1 - .../output.json | 2 -- .../external_reentrancy_crypto.sol | 2 +- .../base_contract_assertion_fail_1.sol | 2 +- .../implicit_constructor_hierarchy.sol | 3 +-- .../operators/conditional_assignment_5.sol | 4 ++- .../operators/conditional_assignment_6.sol | 2 +- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index bfdb0b4289..c0a92264e6 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -1623,28 +1623,23 @@ void CHC::checkVerificationTargets() // Also, all possible contexts in which an external function can be called has been recorded (m_queryPlaceholders). // Here we combine every context in which an external function can be called with all possible verification conditions // in its call graph. Each such combination forms a unique verification target. - vector verificationTargets; + map> targetEntryPoints; for (auto const& [function, placeholders]: m_queryPlaceholders) { auto functionTargets = transactionVerificationTargetsIds(function); for (auto const& placeholder: placeholders) for (unsigned id: functionTargets) - { - auto const& target = m_verificationTargets.at(id); - verificationTargets.push_back(CHCVerificationTarget{ - {target.type, placeholder.fromPredicate, placeholder.constraints && placeholder.errorExpression == target.errorId}, - target.errorId, - target.errorNode - }); - } + targetEntryPoints[id].push_back(placeholder); } set checkedErrorIds; - for (auto const& target: verificationTargets) + for (auto const& [targetId, placeholders]: targetEntryPoints) { string errorType; ErrorId errorReporterId; + auto const& target = m_verificationTargets.at(targetId); + if (target.type == VerificationTargetType::PopEmptyArray) { solAssert(dynamic_cast(target.errorNode), ""); @@ -1692,7 +1687,7 @@ void CHC::checkVerificationTargets() else solAssert(false, ""); - checkAndReportTarget(target, errorReporterId, errorType + " happens here.", errorType + " might happen here."); + checkAndReportTarget(target, placeholders, errorReporterId, errorType + " happens here.", errorType + " might happen here."); checkedErrorIds.insert(target.errorId); } @@ -1750,7 +1745,7 @@ void CHC::checkVerificationTargets() { set seenErrors; msg += " = 0 -> no errors\n"; - for (auto const& target: verificationTargets) + for (auto const& [id, target]: m_verificationTargets) if (!seenErrors.count(target.errorId)) { seenErrors.insert(target.errorId); @@ -1785,6 +1780,7 @@ void CHC::checkVerificationTargets() void CHC::checkAndReportTarget( CHCVerificationTarget const& _target, + vector const& _placeholders, ErrorId _errorReporterId, string _satMsg, string _unknownMsg @@ -1794,7 +1790,12 @@ void CHC::checkAndReportTarget( return; createErrorBlock(); - connectBlocks(_target.value, error(), _target.constraints); + for (auto const& placeholder: _placeholders) + connectBlocks( + placeholder.fromPredicate, + error(), + placeholder.constraints && placeholder.errorExpression == _target.errorId + ); auto const& location = _target.errorNode->location(); auto [result, invariant, model] = query(error(), location); if (result == CheckResult::UNSATISFIABLE) diff --git a/libsolidity/formal/CHC.h b/libsolidity/formal/CHC.h index d9e27a89cc..1c74aa650b 100644 --- a/libsolidity/formal/CHC.h +++ b/libsolidity/formal/CHC.h @@ -252,11 +252,13 @@ class CHC: public SMTEncoder void verificationTargetEncountered(ASTNode const* const _errorNode, VerificationTargetType _type, smtutil::Expression const& _errorCondition); void checkVerificationTargets(); - // Forward declaration. Definition is below. + // Forward declarations. Definitions are below. struct CHCVerificationTarget; + struct CHCQueryPlaceholder; void checkAssertTarget(ASTNode const* _scope, CHCVerificationTarget const& _target); void checkAndReportTarget( CHCVerificationTarget const& _target, + std::vector const& _placeholders, langutil::ErrorId _errorReporterId, std::string _satMsg, std::string _unknownMsg = "" diff --git a/test/cmdlineTests/model_checker_invariants_all/err b/test/cmdlineTests/model_checker_invariants_all/err index 47bc04256e..2f028037bc 100644 --- a/test/cmdlineTests/model_checker_invariants_all/err +++ b/test/cmdlineTests/model_checker_invariants_all/err @@ -7,7 +7,6 @@ Warning: Return value of low-level calls not used. Info: Contract invariant(s) for model_checker_invariants_all/input.sol:test: (x <= 0) Reentrancy property(ies) for model_checker_invariants_all/input.sol:test: -(!(x <= 0) || (x' <= 0)) ((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) ((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) = 0 -> no errors diff --git a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err index 372143657c..fad76665e4 100644 --- a/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err +++ b/test/cmdlineTests/model_checker_invariants_contract_reentrancy/err @@ -7,7 +7,6 @@ Warning: Return value of low-level calls not used. Info: Contract invariant(s) for model_checker_invariants_contract_reentrancy/input.sol:test: (x <= 0) Reentrancy property(ies) for model_checker_invariants_contract_reentrancy/input.sol:test: -(!(x <= 0) || (x' <= 0)) ((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) ((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) = 0 -> no errors diff --git a/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json index 433648d0b9..f5ced72531 100644 --- a/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json +++ b/test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json @@ -7,7 +7,6 @@ ","message":"Return value of low-level calls not used.","severity":"warning","sourceLocation":{"end":143,"file":"A","start":132},"type":"Warning"},{"component":"general","errorCode":"1180","formattedMessage":"Info: Contract invariant(s) for A:test: (x <= 0) Reentrancy property(ies) for A:test: -(!(x <= 0) || (x' <= 0)) ((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) ((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) = 0 -> no errors @@ -18,7 +17,6 @@ Reentrancy property(ies) for A:test: ","message":"Contract invariant(s) for A:test: (x <= 0) Reentrancy property(ies) for A:test: -(!(x <= 0) || (x' <= 0)) ((!(x <= 0) || !( >= 3)) && (!(x <= 0) || (x' <= 0))) ((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0))) = 0 -> no errors diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol index 627f797630..2a79e6c4d2 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol @@ -25,8 +25,8 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreInv: yes // ---- // Warning 1218: (302-333): CHC: Error trying to invoke SMT solver. // Warning 6328: (302-333): CHC: Assertion violation might happen here. -// Info 1180: Contract invariant(s) for :C:\n(((kec + ((- 1) * keccak256(data))) >= 0) && ((kec + ((- 1) * keccak256(data))) <= 0))\nReentrancy property(ies) for :C:\n((!((kec + ((- 1) * keccak256(data))) >= 0) || ((kec' + ((- 1) * keccak256(data'))) >= 0)) && (!((kec + ((- 1) * keccak256(data))) <= 0) || ((kec' + ((- 1) * keccak256(data'))) <= 0)))\n((!( = 1) || !((kec + ((- 1) * keccak256(data))) = 0)) && (!((kec + ((- 1) * keccak256(data))) <= 0) || ((kec' + ((- 1) * keccak256(data'))) <= 0)) && (!((kec + ((- 1) * keccak256(data))) >= 0) || ((kec' + ((- 1) * keccak256(data'))) >= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(_kec == kec)\n = 2 -> Assertion failed at assert(kec == keccak256(_data))\n // Warning 4661: (302-333): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol index 1f05d11765..0fd5086025 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol @@ -15,5 +15,5 @@ contract C is B { // ==== // SMTEngine: all // ---- -// Warning 6328: (52-66): CHC: Assertion violation happens here.\nCounterexample:\ny = 0, x = 1\n\nTransaction trace:\nC.constructor()\nState: y = 0, x = 0\nC.g()\n B.f() -- internal call\nState: y = 0, x = 1\nB.f() +// Warning 6328: (52-66): CHC: Assertion violation happens here.\nCounterexample:\ny = 0, x = 1\n\nTransaction trace:\nC.constructor()\nState: y = 0, x = 0\nC.g()\n B.f() -- internal call // Info 1180: Contract invariant(s) for :B:\n(x <= 0)\n diff --git a/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol b/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol index 59d0423028..c8b2f96c58 100644 --- a/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol +++ b/test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol @@ -15,5 +15,4 @@ contract C is B { // ==== // SMTEngine: all // SMTSolvers: z3 -// ---- -// Info 1180: Contract invariant(s) for :C:\n(!(x <= 1) && !(x >= 3))\n +// SMTIgnoreInv: yes diff --git a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol index 24be3cd8ea..dd467f8532 100644 --- a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol +++ b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol @@ -25,4 +25,6 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 2072: (249-255): Unused local variable. -// Warning 6328: (271-295): CHC: Assertion violation happens here. +// Warning 1218: (271-295): CHC: Error trying to invoke SMT solver. +// Warning 6328: (271-295): CHC: Assertion violation might happen here. +// Warning 4661: (271-295): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol index e37d3f84c2..3b89e1afb2 100644 --- a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol +++ b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol @@ -25,4 +25,4 @@ contract C { // SMTIgnoreOS: macos // ---- // Warning 2072: (255-261): Unused local variable. -// Info 1180: Reentrancy property(ies) for :C:\n((!(x <= 2) || !(x' >= 3)) && ( <= 0) && (!(x' <= 0) || !(x >= 2)))\n((!(x' <= 0) || ((x' + ((- 1) * x)) = 0)) && ( <= 0) && (!(x' >= 3) || ((x' + ((- 1) * x)) = 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 2 || x == 1)\n +// Info 1180: Reentrancy property(ies) for :C:\n((!(x' <= 0) || ((x' + ((- 1) * x)) = 0)) && ( <= 0) && (!(x' >= 3) || ((x' + ((- 1) * x)) = 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 2 || x == 1)\n From b2c9b69de2292c0a7c05bdc3cae6fcfe46d86383 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 13 Aug 2021 00:37:23 +0200 Subject: [PATCH 0059/1748] Enable for IR code generation with stack optimization > homestead. --- libyul/AssemblyStack.h | 4 +-- libyul/backends/evm/EVMObjectCompiler.cpp | 41 ++++++++++++++--------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/libyul/AssemblyStack.h b/libyul/AssemblyStack.h index 950265ca48..743d76dc66 100644 --- a/libyul/AssemblyStack.h +++ b/libyul/AssemblyStack.h @@ -139,9 +139,9 @@ class AssemblyStack: public langutil::CharStreamProvider private: bool analyzeParsed(); bool analyzeParsed(yul::Object& _object); - +public: void compileEVM(yul::AbstractAssembly& _assembly, bool _optimize) const; - +private: void optimize(yul::Object& _object, bool _isCreation); Language m_language = Language::Assembly; diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index e41a683872..c85c1ae921 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -62,19 +63,29 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) yulAssert(_object.analysisInfo, "No analysis info."); yulAssert(_object.code, "No code."); - // We do not catch and re-throw the stack too deep exception here because it is a YulException, - // which should be native to this part of the code. - CodeTransform transform{ - m_assembly, - *_object.analysisInfo, - *_object.code, - m_dialect, - context, - _optimize, - {}, - CodeTransform::UseNamedLabels::ForFirstFunctionOfEachName - }; - transform(*_object.code); - if (!transform.stackErrors().empty()) - BOOST_THROW_EXCEPTION(transform.stackErrors().front()); + if (_optimize && m_dialect.evmVersion().canOverchargeGasForCall()) + { + + auto stackErrors = OptimizedEVMCodeTransform::run(m_assembly, *_object.analysisInfo, *_object.code, m_dialect, context); + if (!stackErrors.empty()) + BOOST_THROW_EXCEPTION(stackErrors.front()); + } + else + { + // We do not catch and re-throw the stack too deep exception here because it is a YulException, + // which should be native to this part of the code. + CodeTransform transform{ + m_assembly, + *_object.analysisInfo, + *_object.code, + m_dialect, + context, + _optimize, + {}, + CodeTransform::UseNamedLabels::ForFirstFunctionOfEachName + }; + transform(*_object.code); + if (!transform.stackErrors().empty()) + BOOST_THROW_EXCEPTION(transform.stackErrors().front()); + } } From 4229369180d2ba0001aa1d4254eb188703d59ff8 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 12 Aug 2021 17:17:21 +0200 Subject: [PATCH 0060/1748] Compatibility with StackCompressor and StackLimitEvader. --- libsolidity/codegen/ir/IRGenerator.cpp | 3 - libyul/optimiser/StackCompressor.cpp | 130 ++++++++++++++++++++----- libyul/optimiser/StackLimitEvader.cpp | 43 ++++++++ libyul/optimiser/StackLimitEvader.h | 20 ++++ libyul/optimiser/Suite.cpp | 38 +++++--- 5 files changed, 193 insertions(+), 41 deletions(-) diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index b17b33c03f..c2bb0c3cf3 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -1069,9 +1069,6 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract) string IRGenerator::memoryInit(bool _useMemoryGuard) { - // TODO: Remove once we have made sure it is safe, i.e. after "Yul memory objects lite". - // Also restore the tests removed in the commit that adds this comment. - _useMemoryGuard = false; // This function should be called at the beginning of the EVM call frame // and thus can assume all memory to be zero, including the contents of // the "zero memory area" (the position CompilerUtils::zeroPointer points to). diff --git a/libyul/optimiser/StackCompressor.cpp b/libyul/optimiser/StackCompressor.cpp index a57d9738b4..2deef5234a 100644 --- a/libyul/optimiser/StackCompressor.cpp +++ b/libyul/optimiser/StackCompressor.cpp @@ -27,6 +27,13 @@ #include #include +#include +#include +#include + +#include +#include + #include #include @@ -162,6 +169,50 @@ void eliminateVariables( UnusedPruner::runUntilStabilised(_dialect, _node, _allowMSizeOptimization); } +void eliminateVariables( + Dialect const& _dialect, + Block& _block, + vector const& _unreachables, + bool _allowMSizeOptimization +) +{ + RematCandidateSelector selector{_dialect}; + selector(_block); + std::map candidates; + for (auto [cost, candidatesWithCost]: selector.candidates()) + for (auto candidate: candidatesWithCost) + candidates[get<0>(candidate)] = cost; + + set varsToEliminate; + + // TODO: this currently ignores the fact that variables may reference other variables we want to eliminate. + for (auto const& unreachable: _unreachables) + { + map> suitableCandidates; + size_t neededSlots = unreachable.deficit; + for (auto varName: unreachable.variableChoices) + { + if (varsToEliminate.count(varName)) + --neededSlots; + else if (size_t* cost = util::valueOrNullptr(candidates, varName)) + if (!util::contains(suitableCandidates[*cost], varName)) + suitableCandidates[*cost].emplace_back(varName); + } + for (auto candidatesByCost: suitableCandidates) + { + for (auto candidate: candidatesByCost.second) + if (neededSlots--) + varsToEliminate.emplace(candidate); + else + break; + if (!neededSlots) + break; + } + } + Rematerialiser::run(_dialect, _block, std::move(varsToEliminate), true); + UnusedPruner::runUntilStabilised(_dialect, _block, _allowMSizeOptimization); +} + } bool StackCompressor::run( @@ -176,39 +227,66 @@ bool StackCompressor::run( _object.code->statements.size() > 0 && holds_alternative(_object.code->statements.at(0)), "Need to run the function grouper before the stack compressor." ); + bool usesOptimizedCodeGenerator = false; + if (auto evmDialect = dynamic_cast(&_dialect)) + usesOptimizedCodeGenerator = + _optimizeStackAllocation && + evmDialect->evmVersion().canOverchargeGasForCall() && + evmDialect->providesObjectAccess(); bool allowMSizeOptimzation = !MSizeFinder::containsMSize(_dialect, *_object.code); - for (size_t iterations = 0; iterations < _maxIterations; iterations++) + if (usesOptimizedCodeGenerator) { - map stackSurplus = CompilabilityChecker(_dialect, _object, _optimizeStackAllocation).stackDeficit; - if (stackSurplus.empty()) - return true; - - if (stackSurplus.count(YulString{})) - { - yulAssert(stackSurplus.at({}) > 0, "Invalid surplus value."); - eliminateVariables( - _dialect, - std::get(_object.code->statements.at(0)), - static_cast(stackSurplus.at({})), - allowMSizeOptimzation - ); - } - + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object); + unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, _dialect, *_object.code); + Block& mainBlock = std::get(_object.code->statements.at(0)); + if ( + auto stackTooDeepErrors = StackLayoutGenerator::reportStackTooDeep(*cfg, YulString{}); + !stackTooDeepErrors.empty() + ) + eliminateVariables(_dialect, mainBlock, stackTooDeepErrors, allowMSizeOptimzation); for (size_t i = 1; i < _object.code->statements.size(); ++i) { auto& fun = std::get(_object.code->statements[i]); - if (!stackSurplus.count(fun.name)) - continue; - - yulAssert(stackSurplus.at(fun.name) > 0, "Invalid surplus value."); - eliminateVariables( - _dialect, - fun, - static_cast(stackSurplus.at(fun.name)), - allowMSizeOptimzation - ); + if ( + auto stackTooDeepErrors = StackLayoutGenerator::reportStackTooDeep(*cfg, fun.name); + !stackTooDeepErrors.empty() + ) + eliminateVariables(_dialect, fun.body, stackTooDeepErrors, allowMSizeOptimzation); } } + else + for (size_t iterations = 0; iterations < _maxIterations; iterations++) + { + map stackSurplus = CompilabilityChecker(_dialect, _object, _optimizeStackAllocation).stackDeficit; + if (stackSurplus.empty()) + return true; + + if (stackSurplus.count(YulString{})) + { + yulAssert(stackSurplus.at({}) > 0, "Invalid surplus value."); + eliminateVariables( + _dialect, + std::get(_object.code->statements.at(0)), + static_cast(stackSurplus.at({})), + allowMSizeOptimzation + ); + } + + for (size_t i = 1; i < _object.code->statements.size(); ++i) + { + auto& fun = std::get(_object.code->statements[i]); + if (!stackSurplus.count(fun.name)) + continue; + + yulAssert(stackSurplus.at(fun.name) > 0, "Invalid surplus value."); + eliminateVariables( + _dialect, + fun, + static_cast(stackSurplus.at(fun.name)), + allowMSizeOptimzation + ); + } + } return false; } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index 1c7903b1f8..b77bd4f388 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -21,14 +21,18 @@ #include #include #include +#include #include +#include #include +#include #include #include #include #include #include +#include #include #include @@ -114,6 +118,45 @@ u256 literalArgumentValue(FunctionCall const& _call) } } +void StackLimitEvader::run( + OptimiserStepContext& _context, + Object& _object +) +{ + auto const* evmDialect = dynamic_cast(&_context.dialect); + yulAssert( + evmDialect && evmDialect->providesObjectAccess(), + "StackLimitEvader can only be run on objects using the EVMDialect with object access." + ); + if (evmDialect && evmDialect->evmVersion().canOverchargeGasForCall()) + { + yul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(*evmDialect, _object); + unique_ptr cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, *_object.code); + run(_context, _object, StackLayoutGenerator::reportStackTooDeep(*cfg)); + } + else + run(_context, _object, CompilabilityChecker{ + _context.dialect, + _object, + true + }.unreachableVariables); + +} + +void StackLimitEvader::run( + OptimiserStepContext& _context, + Object& _object, + map> const& _stackTooDeepErrors +) +{ + map> unreachableVariables; + for (auto&& [function, stackTooDeepErrors]: _stackTooDeepErrors) + // TODO: choose wisely. + for (auto const& stackTooDeepError: stackTooDeepErrors) + unreachableVariables[function] += stackTooDeepError.variableChoices | ranges::views::take(stackTooDeepError.deficit) | ranges::to>; + run(_context, _object, unreachableVariables); +} + void StackLimitEvader::run( OptimiserStepContext& _context, Object& _object, diff --git a/libyul/optimiser/StackLimitEvader.h b/libyul/optimiser/StackLimitEvader.h index 4fc351f73a..ae2d31c375 100644 --- a/libyul/optimiser/StackLimitEvader.h +++ b/libyul/optimiser/StackLimitEvader.h @@ -22,6 +22,7 @@ #pragma once #include +#include namespace solidity::yul { @@ -61,6 +62,25 @@ class StackLimitEvader Object& _object, std::map> const& _unreachableVariables ); + /// @a _stackTooDeepErrors can be determined by the StackLayoutGenerator. + /// Can only be run on the EVM dialect with objects. + /// Abort and do nothing, if no ``memoryguard`` call or several ``memoryguard`` calls + /// with non-matching arguments are found, or if any of the @a _stackTooDeepErrors + /// are contained in a recursive function. + static void run( + OptimiserStepContext& _context, + Object& _object, + std::map> const& _stackTooDeepErrors + ); + /// Determines stack too deep errors using the appropriate code generation backend. + /// Can only be run on the EVM dialect with objects. + /// Abort and do nothing, if no ``memoryguard`` call or several ``memoryguard`` calls + /// with non-matching arguments are found, or if any of the unreachable variables + /// are contained in a recursive function. + static void run( + OptimiserStepContext& _context, + Object& _object + ); }; } diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 5525e17d20..bd81f7c0b4 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -95,6 +95,12 @@ void OptimiserSuite::run( set const& _externallyUsedIdentifiers ) { + EVMDialect const* evmDialect = dynamic_cast(&_dialect); + bool usesOptimizedCodeGenerator = + _optimizeStackAllocation && + evmDialect && + evmDialect->evmVersion().canOverchargeGasForCall() && + evmDialect->providesObjectAccess(); set reservedIdentifiers = _externallyUsedIdentifiers; reservedIdentifiers += _dialect.fixedFunctionNames(); @@ -121,24 +127,32 @@ void OptimiserSuite::run( // We ignore the return value because we will get a much better error // message once we perform code generation. - StackCompressor::run( - _dialect, - _object, - _optimizeStackAllocation, - stackCompressorMaxIterations - ); + if (!usesOptimizedCodeGenerator) + StackCompressor::run( + _dialect, + _object, + _optimizeStackAllocation, + stackCompressorMaxIterations + ); suite.runSequence("fDnTOc g", ast); - if (EVMDialect const* dialect = dynamic_cast(&_dialect)) + if (evmDialect) { yulAssert(_meter, ""); - ConstantOptimiser{*dialect, *_meter}(ast); - if (dialect->providesObjectAccess() && _optimizeStackAllocation) - StackLimitEvader::run(suite.m_context, _object, CompilabilityChecker{ + ConstantOptimiser{*evmDialect, *_meter}(ast); + if (usesOptimizedCodeGenerator) + { + StackCompressor::run( _dialect, _object, - _optimizeStackAllocation - }.unreachableVariables); + _optimizeStackAllocation, + stackCompressorMaxIterations + ); + if (evmDialect->providesObjectAccess()) + StackLimitEvader::run(suite.m_context, _object); + } + else if (evmDialect->providesObjectAccess() && _optimizeStackAllocation) + StackLimitEvader::run(suite.m_context, _object); } else if (dynamic_cast(&_dialect)) { From 1a0605c5940b769179667ca9c2b858c0d6502b17 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 15 Sep 2021 17:01:40 +0200 Subject: [PATCH 0061/1748] Update tests. --- libyul/AssemblyStack.h | 4 +- .../output | 26 +- .../output | 26 +- .../output | 26 +- .../debug_info_in_yul_snippet_escaping/output | 68 +- test/cmdlineTests/exp_base_literal/output | 4 +- .../function_debug_info_via_yul/output | 15 +- .../output | 22 +- .../ir_compiler_subobjects/output | 61 +- .../output | 13 +- .../output | 9 +- .../keccak_optimization_low_runs/output | 9 +- test/cmdlineTests/name_simplifier/output | 11 +- test/cmdlineTests/object_compiler/output | 6 +- .../cmdlineTests/optimizer_array_sload/output | 11 +- test/cmdlineTests/revert_strings/output | 4 +- .../output.json | 1014 +++++++++-------- .../output.json | 26 +- .../output.json | 26 +- .../output.json | 26 +- .../output.json | 58 +- .../standard_ewasm_requested/output.json | 18 +- .../output.json | 4 +- .../standard_ir_requested/output.json | 4 +- .../standard_viair_requested/output.json | 12 +- .../standard_yul_optimiserSteps/output.json | 4 +- .../standard_yul_optimized/output.json | 4 +- .../standard_yul_stack_opt/output.json | 6 +- .../strict_asm_optimizer_steps/output | 21 +- test/cmdlineTests/viair_abicoder_v1/output | 4 +- test/cmdlineTests/viair_subobjects/output | 61 +- test/cmdlineTests/yul_optimize_runs/output | 8 +- test/cmdlineTests/yul_optimizer_steps/output | 4 +- .../output | 4 +- .../yul_string_format_ascii/output.json | 4 +- .../output.json | 4 +- .../output.json | 4 +- .../yul_string_format_ascii_long/output.json | 4 +- .../yul_string_format_hex/output.json | 4 +- test/cmdlineTests/yul_verbatim_msize/output | 4 +- .../abiEncoderV1/abi_decode_v2_storage.sol | 2 +- .../abi_encode_calldata_slice.sol | 4 +- .../struct/struct_storage_ptr.sol | 2 +- .../abi_encode_calldata_slice.sol | 4 +- .../abiEncoderV2/abi_encode_v2.sol | 2 +- ...2_in_function_inherited_in_v1_contract.sol | 2 +- ...ode_v2_in_modifier_used_in_v1_contract.sol | 2 +- .../abiEncoderV2/calldata_array.sol | 2 +- .../abiEncoderV2/storage_array_encoding.sol | 4 +- .../abi_decode_simple_storage.sol | 2 +- .../arrays_complex_from_and_to_storage.sol | 2 +- .../array/byte_array_storage_layout.sol | 2 +- .../array/byte_array_transitional_2.sol | 2 +- .../array/bytes_length_member.sol | 2 +- .../copying/array_copy_calldata_storage.sol | 2 +- .../copying/array_copy_cleanup_uint128.sol | 2 +- .../copying/array_copy_cleanup_uint40.sol | 2 +- .../copying/array_copy_clear_storage.sol | 2 +- .../array_copy_clear_storage_packed.sol | 4 +- .../copying/array_copy_different_packing.sol | 2 +- .../copying/array_copy_including_array.sol | 4 +- .../array/copying/array_copy_nested_array.sol | 2 +- ...ay_copy_storage_storage_different_base.sol | 2 +- ..._storage_storage_different_base_nested.sol | 2 +- .../array_copy_storage_storage_dyn_dyn.sol | 2 +- ...y_copy_storage_storage_dynamic_dynamic.sol | 2 +- ...ay_copy_storage_storage_static_dynamic.sol | 2 +- ...ray_copy_storage_storage_static_static.sol | 2 +- .../array_copy_storage_storage_struct.sol | 2 +- .../array_copy_storage_to_memory_nested.sol | 2 +- .../copying/array_copy_target_leftover.sol | 2 +- .../copying/array_copy_target_leftover2.sol | 2 +- .../copying/array_copy_target_simple.sol | 2 +- .../copying/array_copy_target_simple_2.sol | 2 +- .../array_nested_calldata_to_storage.sol | 8 +- .../array_nested_memory_to_storage.sol | 4 +- .../array_of_struct_calldata_to_storage.sol | 2 +- .../array_of_struct_memory_to_storage.sol | 2 +- ..._containing_arrays_calldata_to_storage.sol | 2 +- ...ts_containing_arrays_memory_to_storage.sol | 2 +- .../array_storage_multi_items_per_slot.sol | 2 +- .../copying/arrays_from_and_to_storage.sol | 2 +- .../array/copying/bytes_inside_mappings.sol | 4 +- .../copying/bytes_storage_to_storage.sol | 10 +- .../calldata_array_dynamic_to_storage.sol | 2 +- .../copy_byte_array_in_struct_to_storage.sol | 4 +- .../copying/copy_byte_array_to_storage.sol | 2 +- .../copying/copy_function_storage_array.sol | 2 +- .../array/copying/copy_removes_bytes_data.sol | 2 +- .../memory_dyn_2d_bytes_to_storage.sol | 2 +- .../array/copying/storage_memory_nested.sol | 2 +- .../copying/storage_memory_nested_bytes.sol | 2 +- .../storage_memory_nested_from_pointer.sol | 2 +- .../copying/storage_memory_nested_struct.sol | 2 +- .../copying/storage_memory_packed_dyn.sol | 2 +- .../array/create_memory_array.sol | 2 +- .../array/delete/bytes_delete_element.sol | 2 +- .../delete/delete_storage_array_packed.sol | 2 +- .../array/dynamic_array_cleanup.sol | 2 +- .../array/dynamic_arrays_in_storage.sol | 2 +- .../array/dynamic_multi_array_cleanup.sol | 2 +- .../array/fixed_array_cleanup.sol | 2 +- .../array/fixed_arrays_as_return_type.sol | 2 +- .../array/function_array_cross_calls.sol | 2 +- .../array/pop/array_pop_array_transition.sol | 2 +- .../array/pop/array_pop_uint16_transition.sol | 2 +- .../array/pop/array_pop_uint24_transition.sol | 2 +- .../array/pop/byte_array_pop_copy_long.sol | 2 +- .../pop/byte_array_pop_long_storage_empty.sol | 2 +- ...ray_pop_long_storage_empty_garbage_ref.sol | 2 +- .../array/pop/byte_array_pop_masking_long.sol | 2 +- .../semanticTests/array/push/array_push.sol | 2 +- .../push/array_push_nested_from_calldata.sol | 2 +- .../array/push/array_push_packed_array.sol | 2 +- .../array/push/array_push_struct.sol | 2 +- .../push/array_push_struct_from_calldata.sol | 2 +- .../array/push/byte_array_push_transition.sol | 2 +- .../array/push/nested_bytes_push.sol | 2 +- .../array/push/push_no_args_2d.sol | 4 +- .../array/push/push_no_args_bytes.sol | 2 +- .../semanticTests/array/reusing_memory.sol | 2 +- .../constructor/arrays_in_constructors.sol | 2 +- .../bytes_in_constructors_packer.sol | 2 +- .../constructor/no_callvalue_check.sol | 2 +- .../events/event_dynamic_array_storage.sol | 2 +- .../events/event_dynamic_array_storage_v2.sol | 2 +- .../event_dynamic_nested_array_storage_v2.sol | 2 +- .../events/event_indexed_mixed.sol | 2 +- .../events/event_indexed_string.sol | 2 +- .../externalContracts/FixedFeeRegistrar.sol | 6 +- .../externalContracts/deposit_contract.sol | 10 +- .../externalContracts/prbmath_signed.sol | 22 +- .../externalContracts/prbmath_unsigned.sol | 22 +- .../externalContracts/ramanujan_pi.sol | 4 +- .../semanticTests/externalContracts/snark.sol | 2 +- .../externalContracts/strings.sol | 12 +- .../functionCall/failed_create.sol | 4 +- .../mapping_array_internal_argument.sol | 2 +- .../functionTypes/store_function.sol | 2 +- .../immutable/multi_creation.sol | 2 +- .../address_overload_resolution.sol | 4 +- ...d_function_calldata_calldata_interface.sol | 2 +- ...ted_function_calldata_memory_interface.sol | 2 +- .../keccak_yul_optimization.sol | 4 +- .../interface_inheritance_conversions.sol | 6 +- .../salted_create/salted_create.sol | 2 +- .../salted_create_with_value.sol | 2 +- .../storage/packed_storage_structs_bytes.sol | 2 +- ...ta_struct_with_nested_array_to_storage.sol | 2 +- .../conversion/recursive_storage_memory.sol | 2 +- .../structs/memory_structs_nested_load.sol | 2 +- ...truct_containing_bytes_copy_and_delete.sol | 2 +- .../semanticTests/structs/struct_copy.sol | 4 +- .../structs/struct_copy_via_local.sol | 2 +- .../struct_delete_storage_nested_small.sol | 2 +- .../struct_delete_storage_with_array.sol | 2 +- ...truct_delete_storage_with_arrays_small.sol | 2 +- .../struct_memory_to_storage_function_ptr.sol | 2 +- .../semanticTests/structs/structs.sol | 2 +- .../userDefinedValueType/calldata.sol | 4 +- .../calldata_to_storage.sol | 6 +- .../userDefinedValueType/erc20.sol | 14 +- .../memory_to_storage.sol | 6 +- ...cost_abstraction_comparison_elementary.sol | 8 +- ...ost_abstraction_comparison_userdefined.sol | 8 +- .../various/destructuring_assignment.sol | 2 +- .../semanticTests/various/erc20.sol | 14 +- .../skip_dynamic_types_for_structs.sol | 2 +- .../various/staticcall_for_view_and_pure.sol | 4 +- .../various/swap_in_storage_overwrite.sol | 2 +- .../viaYul/array_memory_index_access.sol | 2 +- .../viaYul/array_storage_index_access.sol | 16 +- .../array_storage_index_boundary_test.sol | 4 +- .../array_storage_index_zeroed_test.sol | 8 +- .../viaYul/array_storage_length_access.sol | 4 +- .../viaYul/array_storage_push_empty.sol | 4 +- ...rray_storage_push_empty_length_address.sol | 6 +- .../viaYul/array_storage_push_pop.sol | 6 +- test/libyul/EVMCodeTransformTest.cpp | 17 +- .../early_push_on_deep_swap.yul | 54 + test/libyul/evmCodeTransform/literal_loop.yul | 74 ++ .../nonempty_initial_layout.yul | 17 + .../evmCodeTransform/stackReuse/for_1.yul | 27 +- .../evmCodeTransform/stackReuse/for_2.yul | 34 +- .../stackReuse/function_argument_reuse.yul | 42 +- ...ction_argument_reuse_without_retparams.yul | 48 +- .../stackReuse/function_call.yul | 57 +- .../stackReuse/function_many_arguments.yul | 172 ++- .../stackReuse/function_params.yul | 15 +- .../function_params_and_retparams.yul | 29 +- ...ction_params_and_retparams_partly_used.yul | 53 +- .../stackReuse/function_retparam.yul | 21 +- .../stackReuse/function_retparam_block.yul | 30 +- .../function_retparam_declaration.yul | 29 +- .../stackReuse/function_retparam_for.yul | 39 +- .../stackReuse/function_retparam_if.yul | 46 +- .../stackReuse/function_retparam_leave.yul | 28 +- .../stackReuse/function_retparam_read.yul | 39 +- .../function_retparam_unassigned.yul | 24 +- .../function_retparam_unassigned_multiple.yul | 32 +- .../stackReuse/function_trivial.yul | 11 +- .../function_with_body_embedded.yul | 43 +- .../stackReuse/functions_multi_return.yul | 107 +- .../libyul/evmCodeTransform/stackReuse/if.yul | 31 +- .../stackReuse/last_use_in_nested_block.yul | 14 +- .../multi_reuse_same_variable_name.yul | 41 +- .../stackReuse/multi_reuse_single_slot.yul | 26 +- .../multi_reuse_single_slot_nested.yul | 26 +- .../reuse_on_decl_assign_not_same_scope.yul | 14 +- .../reuse_on_decl_assign_to_last_used.yul | 15 +- ...reuse_on_decl_assign_to_last_used_expr.yul | 21 +- .../reuse_on_decl_assign_to_not_last_used.yul | 15 +- .../stackReuse/reuse_slots.yul | 42 +- .../stackReuse/reuse_slots_function.yul | 69 +- .../reuse_slots_function_with_gaps.yul | 77 +- .../stackReuse/reuse_too_deep_slot.yul | 180 +-- .../stackReuse/single_var.yul | 6 +- .../stackReuse/single_var_assigned.yul | 6 +- .../single_var_assigned_plus_code.yul | 17 +- ...ngle_var_assigned_plus_code_and_reused.yul | 22 +- .../evmCodeTransform/stackReuse/smoke.yul | 2 + .../evmCodeTransform/stackReuse/switch.yul | 53 +- test/libyul/evmCodeTransform/stub.yul | 86 ++ .../objectCompiler/long_object_name.yul | 10 +- .../objectCompiler/nested_optimizer.yul | 14 +- .../objectCompiler/simple_optimizer.yul | 10 +- .../yulOptimizerTests/fullSuite/aztec.yul | 90 +- .../fullSuite/stack_compressor_msize.yul | 29 +- .../stackCompressor/inlineInBlock.yul | 2 + .../stackCompressor/inlineInFunction.yul | 2 + .../stackCompressor/unusedPrunerWithMSize.yul | 2 + test/libyul/yulStackLayout/literal_loop.yul | 69 ++ 232 files changed, 2381 insertions(+), 1807 deletions(-) create mode 100644 test/libyul/evmCodeTransform/early_push_on_deep_swap.yul create mode 100644 test/libyul/evmCodeTransform/literal_loop.yul create mode 100644 test/libyul/evmCodeTransform/nonempty_initial_layout.yul create mode 100644 test/libyul/evmCodeTransform/stub.yul create mode 100644 test/libyul/yulStackLayout/literal_loop.yul diff --git a/libyul/AssemblyStack.h b/libyul/AssemblyStack.h index 743d76dc66..950265ca48 100644 --- a/libyul/AssemblyStack.h +++ b/libyul/AssemblyStack.h @@ -139,9 +139,9 @@ class AssemblyStack: public langutil::CharStreamProvider private: bool analyzeParsed(); bool analyzeParsed(yul::Object& _object); -public: + void compileEVM(yul::AbstractAssembly& _assembly, bool _optimize) const; -private: + void optimize(yul::Object& _object, bool _isCreation); Language m_language = Language::Assembly; diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output index 31b0ae463b..1b90e94a31 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output @@ -66,7 +66,7 @@ IR: object "C_6" { code { /// @src 0:60:101 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -97,7 +97,7 @@ object "C_6" { object "C_6_deployed" { code { /// @src 0:60:101 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -182,11 +182,12 @@ object "C_6" { code { { /// @src 0:60:101 "contract C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_6_deployed") - codecopy(128, dataoffset("C_6_deployed"), _1) - return(128, _1) + let _2 := datasize("C_6_deployed") + codecopy(_1, dataoffset("C_6_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol" @@ -194,15 +195,16 @@ object "C_6" { code { { /// @src 0:60:101 "contract C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output index 4d7210d373..86968e71b4 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output @@ -66,7 +66,7 @@ IR: object "C_6" { code { /// @src 0:60:101 - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -97,7 +97,7 @@ object "C_6" { object "C_6_deployed" { code { /// @src 0:60:101 - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -181,11 +181,12 @@ object "C_6" { code { { /// @src 0:60:101 - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_6_deployed") - codecopy(128, dataoffset("C_6_deployed"), _1) - return(128, _1) + let _2 := datasize("C_6_deployed") + codecopy(_1, dataoffset("C_6_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol" @@ -193,15 +194,16 @@ object "C_6" { code { { /// @src 0:60:101 - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output index 0c0fbfa1e2..6a87b0b461 100644 --- a/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output +++ b/test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output @@ -63,7 +63,7 @@ IR: object "C_6" { code { - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -90,7 +90,7 @@ object "C_6" { object "C_6_deployed" { code { - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -171,26 +171,28 @@ Optimized IR: object "C_6" { code { { - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_6_deployed") - codecopy(128, dataoffset("C_6_deployed"), _1) - return(128, _1) + let _2 := datasize("C_6_deployed") + codecopy(_1, dataoffset("C_6_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol" object "C_6_deployed" { code { { - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output index b595a771e7..ae3ee1735e 100644 --- a/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output +++ b/test/cmdlineTests/debug_info_in_yul_snippet_escaping/output @@ -11,7 +11,7 @@ IR: object "C_2" { code { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_2() @@ -42,7 +42,7 @@ object "C_2" { object "C_2_deployed" { code { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(128)) revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() @@ -82,11 +82,12 @@ object "C_2" { code { { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_2_deployed") - codecopy(128, dataoffset("C_2_deployed"), _1) - return(128, _1) + let _2 := datasize("C_2_deployed") + codecopy(_1, dataoffset("C_2_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" @@ -94,7 +95,7 @@ object "C_2" { code { { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } @@ -115,7 +116,7 @@ IR: object "D_27" { code { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_D_27() @@ -146,7 +147,7 @@ object "D_27" { object "D_27_deployed" { code { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -372,7 +373,7 @@ object "D_27" { object "C_2" { code { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_2() @@ -403,7 +404,7 @@ object "D_27" { object "C_2_deployed" { code { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(128)) revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() @@ -448,11 +449,12 @@ object "D_27" { code { { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("D_27_deployed") - codecopy(128, dataoffset("D_27_deployed"), _1) - return(128, _1) + let _2 := datasize("D_27_deployed") + codecopy(_1, dataoffset("D_27_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" @@ -460,26 +462,25 @@ object "D_27" { code { { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } /// @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." - let _2 := datasize("C_2") - let _3 := add(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 128, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _2) - if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 128)) - /// @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." - { panic_error_0x41() } - datacopy(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 128, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ dataoffset("C_2"), _2) - if iszero(create(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ _1, 128, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _2)) + let _3 := datasize("C_2") + let _4 := add(_1, _3) + if or(gt(_4, 0xffffffffffffffff), lt(_4, _1)) { panic_error_0x41() } + datacopy(_1, dataoffset("C_2"), _3) + if iszero(create(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ _2, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _1, sub(_4, _1))) { /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." let pos := mload(64) - returndatacopy(pos, _1, returndatasize()) + returndatacopy(pos, _2, returndatasize()) revert(pos, returndatasize()) } mstore(add(allocate_memory_array_string(), 32), "/*") @@ -539,11 +540,12 @@ object "D_27" { code { { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_2_deployed") - codecopy(128, dataoffset("C_2_deployed"), _1) - return(128, _1) + let _2 := datasize("C_2_deployed") + codecopy(_1, dataoffset("C_2_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"debug_info_in_yul_snippet_escaping/input.sol" @@ -551,7 +553,7 @@ object "D_27" { code { { /// @src 0:265:278 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } diff --git a/test/cmdlineTests/exp_base_literal/output b/test/cmdlineTests/exp_base_literal/output index 9c3efdc1f2..77893da189 100644 --- a/test/cmdlineTests/exp_base_literal/output +++ b/test/cmdlineTests/exp_base_literal/output @@ -11,7 +11,7 @@ IR: object "C_81" { code { /// @src 0:82:370 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_81() @@ -42,7 +42,7 @@ object "C_81" { object "C_81_deployed" { code { /// @src 0:82:370 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/function_debug_info_via_yul/output b/test/cmdlineTests/function_debug_info_via_yul/output index 8b952a9e97..5af245ce4a 100644 --- a/test/cmdlineTests/function_debug_info_via_yul/output +++ b/test/cmdlineTests/function_debug_info_via_yul/output @@ -4,20 +4,7 @@ "function_debug_info_via_yul/input.sol:C": { "function-debug": {}, - "function-debug-runtime": - { - "abi_encode_uint256": - { - "parameterSlots": 2, - "returnSlots": 1 - }, - "calldata_array_index_access_uint256_dyn_calldata": - { - "entryPoint": 168, - "parameterSlots": 2, - "returnSlots": 1 - } - } + "function-debug-runtime": {} } }, "version": "" diff --git a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output index 12c61e7838..330e208f45 100644 --- a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output +++ b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output @@ -11,11 +11,12 @@ object "C_7" { code { { /// @src 0:82:117 "contract C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_7_deployed") - codecopy(128, dataoffset("C_7_deployed"), _1) - return(128, _1) + let _2 := datasize("C_7_deployed") + codecopy(_1, dataoffset("C_7_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" @@ -23,7 +24,7 @@ object "C_7" { code { { /// @src 0:82:117 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } @@ -44,11 +45,12 @@ object "D_10" { code { { /// @src 0:118:137 "contract D is C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("D_10_deployed") - codecopy(128, dataoffset("D_10_deployed"), _1) - return(128, _1) + let _2 := datasize("D_10_deployed") + codecopy(_1, dataoffset("D_10_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol" @@ -56,7 +58,7 @@ object "D_10" { code { { /// @src 0:118:137 "contract D is C {..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } diff --git a/test/cmdlineTests/ir_compiler_subobjects/output b/test/cmdlineTests/ir_compiler_subobjects/output index 8c23c8ad75..fbedf38db8 100644 --- a/test/cmdlineTests/ir_compiler_subobjects/output +++ b/test/cmdlineTests/ir_compiler_subobjects/output @@ -11,11 +11,12 @@ object "C_3" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_3_deployed") - codecopy(128, dataoffset("C_3_deployed"), _1) - return(128, _1) + let _2 := datasize("C_3_deployed") + codecopy(_1, dataoffset("C_3_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_compiler_subobjects/input.sol" @@ -23,7 +24,7 @@ object "C_3" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } @@ -44,11 +45,12 @@ object "D_16" { code { { /// @src 0:96:165 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("D_16_deployed") - codecopy(128, dataoffset("D_16_deployed"), _1) - return(128, _1) + let _2 := datasize("D_16_deployed") + codecopy(_1, dataoffset("D_16_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_compiler_subobjects/input.sol" @@ -56,35 +58,35 @@ object "D_16" { code { { /// @src 0:96:165 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - /// @src 0:149:156 "new C()" - let _2 := datasize("C_3") - let _3 := add(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ _2) - if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:96:165 "contract D {..." */ 128)) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } /// @src 0:149:156 "new C()" + let _3 := datasize("C_3") + let _4 := add(_1, _3) + if or(gt(_4, 0xffffffffffffffff), lt(_4, _1)) { /// @src 0:96:165 "contract D {..." - mstore(_1, shl(224, 0x4e487b71)) + mstore(_2, shl(224, 0x4e487b71)) mstore(4, 0x41) - revert(_1, 0x24) + revert(_2, 0x24) } /// @src 0:149:156 "new C()" - datacopy(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ dataoffset("C_3"), _2) - if iszero(create(/** @src 0:96:165 "contract D {..." */ _1, 128, /** @src 0:149:156 "new C()" */ _2)) + datacopy(_1, dataoffset("C_3"), _3) + if iszero(create(/** @src 0:96:165 "contract D {..." */ _2, /** @src 0:149:156 "new C()" */ _1, sub(_4, _1))) { /// @src 0:96:165 "contract D {..." let pos := mload(64) - returndatacopy(pos, _1, returndatasize()) + returndatacopy(pos, _2, returndatasize()) revert(pos, returndatasize()) } - return(mload(64), _1) + return(mload(64), _2) } } revert(0, 0) @@ -95,11 +97,12 @@ object "D_16" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_3_deployed") - codecopy(128, dataoffset("C_3_deployed"), _1) - return(128, _1) + let _2 := datasize("C_3_deployed") + codecopy(_1, dataoffset("C_3_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_compiler_subobjects/input.sol" @@ -107,7 +110,7 @@ object "D_16" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output index 930899aead..34b72f8b8e 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output @@ -23,15 +23,16 @@ object "D_12" { code { { /// @src 0:82:161 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output index da6540fa78..cc95451e6d 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output @@ -11,11 +11,12 @@ object "D_8" { code { { /// @src 0:82:153 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("D_8_deployed") - codecopy(128, dataoffset("D_8_deployed"), _1) - return(128, _1) + let _2 := datasize("D_8_deployed") + codecopy(_1, dataoffset("D_8_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"ir_with_assembly_no_memoryguard_runtime/input.sol" diff --git a/test/cmdlineTests/keccak_optimization_low_runs/output b/test/cmdlineTests/keccak_optimization_low_runs/output index 25b678ee04..f5df14027a 100644 --- a/test/cmdlineTests/keccak_optimization_low_runs/output +++ b/test/cmdlineTests/keccak_optimization_low_runs/output @@ -11,11 +11,12 @@ object "C_7" { code { { /// @src 0:62:285 "contract C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_7_deployed") - codecopy(128, dataoffset("C_7_deployed"), _1) - return(128, _1) + let _2 := datasize("C_7_deployed") + codecopy(_1, dataoffset("C_7_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"keccak_optimization_low_runs/input.sol" diff --git a/test/cmdlineTests/name_simplifier/output b/test/cmdlineTests/name_simplifier/output index 44852d1a82..57a4cb594b 100644 --- a/test/cmdlineTests/name_simplifier/output +++ b/test/cmdlineTests/name_simplifier/output @@ -11,11 +11,12 @@ object "C_59" { code { { /// @src 0:346:625 "contract C {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_59_deployed") - codecopy(128, dataoffset("C_59_deployed"), _1) - return(128, _1) + let _2 := datasize("C_59_deployed") + codecopy(_1, dataoffset("C_59_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"name_simplifier/input.sol" @@ -23,7 +24,7 @@ object "C_59" { code { { /// @src 0:346:625 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { let _1 := 0 diff --git a/test/cmdlineTests/object_compiler/output b/test/cmdlineTests/object_compiler/output index eb8a3286e1..93d7b77955 100644 --- a/test/cmdlineTests/object_compiler/output +++ b/test/cmdlineTests/object_compiler/output @@ -23,7 +23,7 @@ object "MyContract" { Binary representation: -33600055600b806011600039806000f3fe60005460005260206000f3 +33600055600b8060106000396000f3fe60005460005260206000f3 Text representation: /* "object_compiler/input.yul":128:136 */ @@ -34,15 +34,13 @@ Text representation: sstore /* "object_compiler/input.yul":240:259 */ dataSize(sub_0) - dup1 /* "object_compiler/input.yul":217:238 */ + dup1 dataOffset(sub_0) /* "object_compiler/input.yul":125:126 */ 0x00 /* "object_compiler/input.yul":205:260 */ codecopy - /* "object_compiler/input.yul":275:294 */ - dup1 /* "object_compiler/input.yul":125:126 */ 0x00 /* "object_compiler/input.yul":265:295 */ diff --git a/test/cmdlineTests/optimizer_array_sload/output b/test/cmdlineTests/optimizer_array_sload/output index 448b0badc6..8404525f8c 100644 --- a/test/cmdlineTests/optimizer_array_sload/output +++ b/test/cmdlineTests/optimizer_array_sload/output @@ -11,11 +11,12 @@ object "Arraysum_34" { code { { /// @src 0:80:429 "contract Arraysum {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("Arraysum_34_deployed") - codecopy(128, dataoffset("Arraysum_34_deployed"), _1) - return(128, _1) + let _2 := datasize("Arraysum_34_deployed") + codecopy(_1, dataoffset("Arraysum_34_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"optimizer_array_sload/input.sol" @@ -23,7 +24,7 @@ object "Arraysum_34" { code { { /// @src 0:80:429 "contract Arraysum {..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { let _1 := 0 diff --git a/test/cmdlineTests/revert_strings/output b/test/cmdlineTests/revert_strings/output index 9ca27eac47..d13f9f4e5e 100644 --- a/test/cmdlineTests/revert_strings/output +++ b/test/cmdlineTests/revert_strings/output @@ -11,7 +11,7 @@ IR: object "C_15" { code { /// @src 0:59:147 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_15() @@ -57,7 +57,7 @@ object "C_15" { object "C_15_deployed" { code { /// @src 0:59:147 "contract C {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json index 3b25e108a8..d8877a82ba 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json @@ -1,297 +1,298 @@ {"contracts":{"C":{"C":{"evm":{"assembly":" /* \"C\":79:428 contract C... */ - mstore(0x40, 0xa0) - jumpi(tag_2, iszero(callvalue)) - 0x00 + 0xa0 dup1 - revert -tag_2: + 0x40 + mstore + jumpi(tag_5, callvalue) + 0x1f bytecodeSize codesize dup2 swap1 sub - 0xa0 - 0x1f + swap2 dup3 add not(0x1f) and - dup2 + dup4 add - swap1 + swap2 sub(shl(0x40, 0x01), 0x01) - dup3 + dup4 gt - swap1 - dup3 + dup5 + dup5 lt or - iszero tag_3 jumpi - mstore(0x00, shl(0xe0, 0x4e487b71)) - mstore(0x04, 0x41) - revert(0x00, 0x24) -tag_3: + dup1 + dup5 + swap3 + 0x20 + swap5 0x40 mstore - dup1 - dup3 - 0xa0 + dup4 codecopy - 0x20 dup2 + add + sub slt - iszero - tag_4 - jumpi - 0x00 - dup1 - revert -tag_4: - pop - pop tag_5 - mload(0xa0) + jumpi + mload /* \"C\":147:149 42 */ mstore(0x80, 0x2a) /* \"C\":203:219 stateVar = _init */ 0x00 /* \"C\":79:428 contract C... */ sstore - /* \"C\":175:223 constructor(int _init)... */ - jump - /* \"C\":79:428 contract C... */ -tag_5: mload(0x40) dataSize(sub_0) - dup1 + swap1 + dup2 dataOffset(sub_0) - dup4 + dup3 codecopy mload(0x80) - dup3 + dup2 assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - dup1 - dup3 return +tag_5: + pop + 0x00 + dup1 + revert +tag_3: + pop + pop + pop + pop + mstore(0x00, shl(0xe0, 0x4e487b71)) + mstore(0x04, 0x41) + revert(0x00, 0x24) stop sub_0: assembly { /* \"C\":79:428 contract C... */ mstore(0x40, 0x80) - jumpi(tag_8, lt(calldatasize, 0x04)) + jumpi(tag_1, iszero(lt(calldatasize, 0x04))) + 0x00 + dup1 + revert + tag_1: 0x00 dup1 calldataload 0xe0 shr + dup1 0x26121ff0 - dup2 eq - tag_10 + tag_3 jumpi + dup1 0x793816ec - dup2 eq - tag_11 + tag_5 jumpi 0x9942ec6f - dup2 eq - tag_12 + tag_7 jumpi - jump(tag_9) - tag_10: - jumpi(tag_13, iszero(callvalue)) - dup2 - dup3 + pop + 0x00 + dup1 revert - tag_13: - tag_14 + tag_7: + jumpi(tag_9, callvalue) + pop + tag_11 calldatasize - tag_1 + tag_12 jump\t// in - tag_14: - /* \"C\":279:298 constVar + immutVar */ + tag_11: + tag_13 + /* \"C\":375:378 int */ + tag_14 tag_15 - /* \"C\":290:298 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":279:298 constVar + immutVar */ - tag_4 jump\t// in - tag_15: + tag_14: /* \"C\":79:428 contract C... */ mload(0x40) - dup2 + swap1 dup2 mstore - 0x20 - dup2 - return - tag_11: - jumpi(tag_17, iszero(callvalue)) + swap1 dup2 + swap1 + 0x20 dup3 + add + swap1 + jump + tag_13: + sub + swap1 + return + tag_9: + dup1 revert - tag_17: - tag_18 + tag_5: + pop + jumpi(tag_9, callvalue) + tag_13 + swap1 + tag_20 calldatasize - tag_1 + tag_12 jump\t// in - tag_18: - dup2 + tag_20: sload mload(0x40) - dup2 + swap1 dup2 mstore - 0x20 - dup2 - return - tag_12: - jumpi(tag_20, iszero(callvalue)) + swap1 dup2 + swap1 + 0x20 dup3 - revert - tag_20: - tag_21 + add + swap1 + jump + tag_3: + pop + jumpi(tag_9, callvalue) + pop + tag_23 calldatasize - tag_1 + tag_12 jump\t// in - tag_21: - /* \"C\":375:378 int */ - tag_15 - tag_6 + tag_23: + tag_13 + /* \"C\":279:298 constVar + immutVar */ + tag_14 + /* \"C\":290:298 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":279:298 constVar + immutVar */ + tag_26 jump\t// in /* \"C\":79:428 contract C... */ - tag_9: - pop - pop - tag_8: - 0x00 - dup1 - revert - tag_1: + tag_12: 0x00 + swap1 not(0x03) - dup3 add slt - iszero - tag_26 + tag_27 jumpi + jump\t// out + tag_27: + pop 0x00 dup1 revert - tag_26: - pop - jump\t// out /* \"C\":117:119 41 */ - tag_3: + tag_29: + pop mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x11) revert(0x00, 0x24) - tag_4: - 0x00 + tag_26: sub(shl(0xff, 0x01), 0x2a) - dup3 + dup2 sgt 0x01 and - iszero - tag_31 + tag_30 jumpi - tag_31 - tag_3 - jump\t// in tag_31: - pop 0x29 add swap1 jump\t// out - tag_5: + tag_30: + tag_32 + tag_29 + jump\t// in + tag_32: + jump(tag_31) + tag_33: 0x00 - dup1 - dup3 + dup2 slt dup1 iszero sub(shl(0xff, 0x01), 0x01) - dup5 + dup4 swap1 sub - dup6 + dup5 sgt and - iszero tag_34 jumpi - tag_34 - tag_3 - jump\t// in - tag_34: + tag_35: shl(0xff, 0x01) - dup4 + dup3 swap1 sub - dup5 + dup4 slt - dup2 and - iszero tag_36 jumpi - tag_36 - tag_3 - jump\t// in + add + swap1 + jump\t// out tag_36: - pop - pop + tag_38 + tag_29 + jump\t// in + tag_38: add swap1 jump\t// out + tag_34: + tag_39 + tag_29 + jump\t// in + tag_39: + jump(tag_35) /* \"C\":304:341 modifier m()... */ - tag_6: - 0x00 + tag_15: /* \"C\":79:428 contract C... */ + 0x00 dup1 sload - /* \"C\":304:341 modifier m()... */ - dup2 + /* \"C\":117:119 41 */ + 0x01 swap1 sub(shl(0xff, 0x01), 0x01) /* \"C\":79:428 contract C... */ dup2 eq - iszero - tag_39 + tag_40 jumpi - tag_39 - tag_3 - jump\t// in - tag_39: - /* \"C\":117:119 41 */ - 0x01 + /* \"C\":304:341 modifier m()... */ + tag_41: /* \"C\":79:428 contract C... */ add - dup1 - dup3 + swap1 + dup2 + dup2 sstore /* \"C\":403:407 this */ address /* \"C\":403:411 this.f() */ extcodesize - tag_40 + iszero + tag_42 jumpi /* \"C\":79:428 contract C... */ - dup2 - dup3 - revert - /* \"C\":403:411 this.f() */ - tag_40: - /* \"C\":79:428 contract C... */ mload(0x40) shl(0xe4, 0x026121ff) /* \"C\":403:411 this.f() */ @@ -309,196 +310,239 @@ sub_0: assembly { /* \"C\":403:411 this.f() */ gas staticcall - dup1 - tag_41 - jumpi - /* \"C\":79:428 contract C... */ - mload(0x40) - returndatasize - dup6 + swap2 dup3 - returndatacopy - returndatasize - dup2 - revert - /* \"C\":403:411 this.f() */ - tag_41: - /* \"C\":79:428 contract C... */ - dup4 - /* \"C\":403:411 this.f() */ - dup2 iszero - tag_42 + tag_44 jumpi - returndatasize - /* \"C\":79:428 contract C... */ - 0x1f - add - not(0x1f) + dup1 + swap3 + tag_46 + jumpi + /* \"C\":304:341 modifier m()... */ + tag_47: + /* \"C\":392:411 stateVar + this.f() */ + pop + pop + tag_48 + swap1 + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_49 + /* \"C\":392:411 stateVar + this.f() */ + swap3 + tag_33 + jump\t// in + tag_48: + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ + swap1 + tag_33 + jump\t// in + tag_49: + /* \"C\":304:341 modifier m()... */ + swap1 + jump\t// out + /* \"C\":403:411 this.f() */ + tag_46: + /* \"C\":79:428 contract C... */ + swap1 + swap2 + pop + /* \"C\":403:411 this.f() */ + returndatasize + /* \"C\":79:428 contract C... */ + 0x1f + add + not(0x1f) and - dup4 + dup3 add + swap1 0xffffffffffffffff - dup2 - gt - dup5 dup3 + gt + dup4 + dup4 lt or - iszero - tag_43 + tag_50 jumpi - shl(0xe0, 0x4e487b71) - dup7 - mstore - 0x41 + pop + swap2 /* \"C\":403:411 this.f() */ - 0x04 + tag_52 + /* \"C\":392:411 stateVar + this.f() */ + tag_48 /* \"C\":79:428 contract C... */ - mstore - 0x24 - dup7 - revert - tag_43: + swap3 + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_49 + /* \"C\":79:428 contract C... */ + swap5 0x40 mstore /* \"C\":403:411 this.f() */ - tag_44 returndatasize - dup5 + dup2 add - dup5 - tag_7 - jump\t// in - tag_44: swap1 + tag_53 + jump\t// in + tag_52: + swap2 + dup2 + swap4 pop - tag_42: - /* \"C\":392:411 stateVar + this.f() */ - tag_45 + jump(tag_47) + /* \"C\":79:428 contract C... */ + tag_50: + shl(0xe0, 0x4e487b71) dup2 - dup6 - tag_5 - jump\t// in - tag_45: + mstore + 0x41 + /* \"C\":403:411 this.f() */ + 0x04 + /* \"C\":79:428 contract C... */ + mstore + 0x24 swap5 pop + /* \"C\":117:119 41 */ + swap3 pop pop pop + /* \"C\":79:428 contract C... */ + revert + /* \"C\":403:411 this.f() */ + tag_44: + /* \"C\":79:428 contract C... */ + swap4 pop - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_46 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ + pop + pop + pop + mload(0x40) + swap1 + returndatasize + swap1 dup3 - tag_5 - jump\t// in - tag_46: - /* \"C\":336:337 _ */ + returndatacopy + returndatasize + swap1 + revert + /* \"C\":403:411 this.f() */ + tag_42: + /* \"C\":79:428 contract C... */ swap2 pop pop - /* \"C\":304:341 modifier m()... */ + dup1 + revert + tag_40: + tag_54 + tag_29 + jump\t// in + tag_54: + jump(tag_41) + tag_53: swap1 - jump\t// out - /* \"C\":79:428 contract C... */ - tag_7: - 0x00 + dup2 0x20 - dup3 - dup5 + swap2 sub slt - iszero - tag_48 + tag_55 jumpi - 0x00 - dup1 - revert - tag_48: - pop mload - swap2 swap1 - pop jump\t// out + tag_55: + pop + pop + 0x00 + dup1 + revert auxdata: } "}}},"D":{"D":{"evm":{"assembly":" /* \"D\":91:166 contract D is C(3)... */ - mstore(0x40, 0xa0) - jumpi(tag_2, iszero(callvalue)) - 0x00 + 0xa0 dup1 - revert -tag_2: + 0x40 + mstore + jumpi(tag_5, callvalue) + 0x1f bytecodeSize codesize dup2 swap1 sub - 0xa0 - 0x1f + swap2 dup3 add not(0x1f) and - dup2 + dup4 add - swap1 + swap2 sub(shl(0x40, 0x01), 0x01) - dup3 + dup4 gt - swap1 - dup3 + dup5 + dup5 lt or - iszero tag_3 jumpi - mstore(0x00, shl(0xe0, 0x4e487b71)) - mstore(0x04, 0x41) - revert(0x00, 0x24) -tag_3: + dup1 + dup5 + swap3 + 0x20 + swap5 0x40 mstore - dup1 - dup3 - 0xa0 + dup4 codecopy - 0x20 dup2 + add + sub slt - iszero - tag_4 - jumpi - 0x00 - dup1 - revert -tag_4: - pop - pop tag_5 - mload(0xa0) - tag_1 + jumpi + tag_7 + swap1 + mload + tag_8 jump\t// in -tag_5: +tag_7: mload(0x40) dataSize(sub_0) - dup1 + swap1 + dup2 dataOffset(sub_0) - dup4 + dup3 codecopy mload(0x80) - dup3 + dup2 assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - dup1 - dup3 return +tag_5: + pop + 0x00 + dup1 + revert +tag_3: + pop + pop + pop + pop + mstore(0x00, shl(0xe0, 0x4e487b71)) + mstore(0x04, 0x41) + revert(0x00, 0x24) /* \"D\":113:164 constructor(int _init2)... */ -tag_1: +tag_8: /* \"C\":147:149 42 */ mstore(0x80, 0x2a) /* \"D\":107:108 3 */ @@ -512,9 +556,22 @@ tag_1: sgt 0x01 and - iszero - tag_8 + tag_9 jumpi + /* \"D\":107:108 3 */ + 0x03 + /* \"D\":91:166 contract D is C(3)... */ + add + /* \"C\":203:219 stateVar = _init */ + 0x00 + /* \"D\":91:166 contract D is C(3)... */ + sstore + /* \"D\":113:164 constructor(int _init2)... */ + jump\t// out + /* \"D\":91:166 contract D is C(3)... */ +tag_9: + pop + pop shl(0xe0, 0x4e487b71) /* \"C\":203:219 stateVar = _init */ 0x00 @@ -526,234 +583,226 @@ tag_1: 0x00 /* \"D\":91:166 contract D is C(3)... */ revert -tag_8: - /* \"D\":107:108 3 */ - 0x03 - /* \"D\":91:166 contract D is C(3)... */ - add - /* \"C\":203:219 stateVar = _init */ - 0x00 - /* \"D\":91:166 contract D is C(3)... */ - sstore - /* \"D\":113:164 constructor(int _init2)... */ - jump\t// out stop sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ mstore(0x40, 0x80) - jumpi(tag_8, lt(calldatasize, 0x04)) + jumpi(tag_1, iszero(lt(calldatasize, 0x04))) + 0x00 + dup1 + revert + tag_1: 0x00 dup1 calldataload 0xe0 shr + dup1 0x26121ff0 - dup2 eq - tag_10 + tag_3 jumpi + dup1 0x793816ec - dup2 eq - tag_11 + tag_5 jumpi 0x9942ec6f - dup2 eq - tag_12 + tag_7 jumpi - jump(tag_9) - tag_10: - jumpi(tag_13, iszero(callvalue)) - dup2 - dup3 + pop + 0x00 + dup1 revert - tag_13: - tag_14 + tag_7: + jumpi(tag_9, callvalue) + pop + tag_11 calldatasize - tag_1 + tag_12 jump\t// in - tag_14: - /* \"C\":279:298 constVar + immutVar */ + tag_11: + tag_13 + /* \"C\":375:378 int */ + tag_14 tag_15 - /* \"C\":290:298 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":279:298 constVar + immutVar */ - tag_4 jump\t// in - tag_15: + tag_14: /* \"D\":91:166 contract D is C(3)... */ mload(0x40) - dup2 + swap1 dup2 mstore - 0x20 - dup2 - return - tag_11: - jumpi(tag_17, iszero(callvalue)) + swap1 dup2 + swap1 + 0x20 dup3 + add + swap1 + jump + tag_13: + sub + swap1 + return + tag_9: + dup1 revert - tag_17: - tag_18 + tag_5: + pop + jumpi(tag_9, callvalue) + tag_13 + swap1 + tag_20 calldatasize - tag_1 + tag_12 jump\t// in - tag_18: - dup2 + tag_20: sload mload(0x40) + swap1 dup2 - dup2 - mstore - 0x20 - dup2 - return - tag_12: - jumpi(tag_20, iszero(callvalue)) - dup2 + mstore + swap1 + dup2 + swap1 + 0x20 dup3 - revert - tag_20: - tag_21 + add + swap1 + jump + tag_3: + pop + jumpi(tag_9, callvalue) + pop + tag_23 calldatasize - tag_1 + tag_12 jump\t// in - tag_21: - /* \"C\":375:378 int */ - tag_15 - tag_6 + tag_23: + tag_13 + /* \"C\":279:298 constVar + immutVar */ + tag_14 + /* \"C\":290:298 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":279:298 constVar + immutVar */ + tag_26 jump\t// in /* \"D\":91:166 contract D is C(3)... */ - tag_9: - pop - pop - tag_8: - 0x00 - dup1 - revert - tag_1: + tag_12: 0x00 + swap1 not(0x03) - dup3 add slt - iszero - tag_26 + tag_27 jumpi + jump\t// out + tag_27: + pop 0x00 dup1 revert - tag_26: - pop - jump\t// out /* \"C\":117:119 41 */ - tag_3: + tag_29: + pop mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x11) revert(0x00, 0x24) - tag_4: - 0x00 + tag_26: sub(shl(0xff, 0x01), 0x2a) - dup3 + dup2 sgt 0x01 and - iszero - tag_31 + tag_30 jumpi - tag_31 - tag_3 - jump\t// in tag_31: - pop 0x29 add swap1 jump\t// out - tag_5: + tag_30: + tag_32 + tag_29 + jump\t// in + tag_32: + jump(tag_31) + tag_33: 0x00 - dup1 - dup3 + dup2 slt dup1 iszero sub(shl(0xff, 0x01), 0x01) - dup5 + dup4 swap1 sub - dup6 + dup5 sgt and - iszero tag_34 jumpi - tag_34 - tag_3 - jump\t// in - tag_34: + tag_35: shl(0xff, 0x01) - dup4 + dup3 swap1 sub - dup5 + dup4 slt - dup2 and - iszero tag_36 jumpi - tag_36 - tag_3 - jump\t// in + add + swap1 + jump\t// out tag_36: - pop - pop + tag_38 + tag_29 + jump\t// in + tag_38: add swap1 jump\t// out + tag_34: + tag_39 + tag_29 + jump\t// in + tag_39: + jump(tag_35) /* \"C\":304:341 modifier m()... */ - tag_6: - 0x00 + tag_15: /* \"D\":91:166 contract D is C(3)... */ + 0x00 dup1 sload - /* \"C\":304:341 modifier m()... */ - dup2 + /* \"C\":117:119 41 */ + 0x01 swap1 sub(shl(0xff, 0x01), 0x01) /* \"D\":91:166 contract D is C(3)... */ dup2 eq - iszero - tag_39 + tag_40 jumpi - tag_39 - tag_3 - jump\t// in - tag_39: - /* \"C\":117:119 41 */ - 0x01 + /* \"C\":304:341 modifier m()... */ + tag_41: /* \"D\":91:166 contract D is C(3)... */ add - dup1 - dup3 + swap1 + dup2 + dup2 sstore /* \"C\":403:407 this */ address /* \"C\":403:411 this.f() */ extcodesize - tag_40 + iszero + tag_42 jumpi /* \"D\":91:166 contract D is C(3)... */ - dup2 - dup3 - revert - /* \"C\":403:411 this.f() */ - tag_40: - /* \"D\":91:166 contract D is C(3)... */ mload(0x40) shl(0xe4, 0x026121ff) /* \"C\":403:411 this.f() */ @@ -771,121 +820,160 @@ sub_0: assembly { /* \"C\":403:411 this.f() */ gas staticcall + swap2 + dup3 + iszero + tag_44 + jumpi dup1 - tag_41 + swap3 + tag_46 jumpi - /* \"D\":91:166 contract D is C(3)... */ - mload(0x40) - returndatasize - dup6 - dup3 - returndatacopy - returndatasize - dup2 - revert + /* \"C\":304:341 modifier m()... */ + tag_47: + /* \"C\":392:411 stateVar + this.f() */ + pop + pop + tag_48 + swap1 + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_49 + /* \"C\":392:411 stateVar + this.f() */ + swap3 + tag_33 + jump\t// in + tag_48: + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ + swap1 + tag_33 + jump\t// in + tag_49: + /* \"C\":304:341 modifier m()... */ + swap1 + jump\t// out /* \"C\":403:411 this.f() */ - tag_41: + tag_46: /* \"D\":91:166 contract D is C(3)... */ - dup4 + swap1 + swap2 + pop /* \"C\":403:411 this.f() */ - dup2 - iszero - tag_42 - jumpi returndatasize /* \"D\":91:166 contract D is C(3)... */ 0x1f add not(0x1f) and - dup4 + dup3 add + swap1 0xffffffffffffffff - dup2 - gt - dup5 dup3 + gt + dup4 + dup4 lt or - iszero - tag_43 + tag_50 jumpi - shl(0xe0, 0x4e487b71) - dup7 - mstore - 0x41 + pop + swap2 /* \"C\":403:411 this.f() */ - 0x04 + tag_52 + /* \"C\":392:411 stateVar + this.f() */ + tag_48 /* \"D\":91:166 contract D is C(3)... */ - mstore - 0x24 - dup7 - revert - tag_43: + swap3 + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_49 + /* \"D\":91:166 contract D is C(3)... */ + swap5 0x40 mstore /* \"C\":403:411 this.f() */ - tag_44 returndatasize - dup5 + dup2 add - dup5 - tag_7 - jump\t// in - tag_44: swap1 + tag_53 + jump\t// in + tag_52: + swap2 + dup2 + swap4 pop - tag_42: - /* \"C\":392:411 stateVar + this.f() */ - tag_45 + jump(tag_47) + /* \"D\":91:166 contract D is C(3)... */ + tag_50: + shl(0xe0, 0x4e487b71) dup2 - dup6 - tag_5 - jump\t// in - tag_45: + mstore + 0x41 + /* \"C\":403:411 this.f() */ + 0x04 + /* \"D\":91:166 contract D is C(3)... */ + mstore + 0x24 swap5 pop + /* \"C\":117:119 41 */ + swap3 pop pop pop + /* \"D\":91:166 contract D is C(3)... */ + revert + /* \"C\":403:411 this.f() */ + tag_44: + /* \"D\":91:166 contract D is C(3)... */ + swap4 pop - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_46 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ + pop + pop + pop + mload(0x40) + swap1 + returndatasize + swap1 dup3 - tag_5 - jump\t// in - tag_46: - /* \"C\":336:337 _ */ + returndatacopy + returndatasize + swap1 + revert + /* \"C\":403:411 this.f() */ + tag_42: + /* \"D\":91:166 contract D is C(3)... */ swap2 pop pop - /* \"C\":304:341 modifier m()... */ + dup1 + revert + tag_40: + tag_54 + tag_29 + jump\t// in + tag_54: + jump(tag_41) + tag_53: swap1 - jump\t// out - /* \"D\":91:166 contract D is C(3)... */ - tag_7: - 0x00 + dup2 0x20 - dup3 - dup5 + swap2 sub slt - iszero - tag_48 + tag_55 jumpi - 0x00 - dup1 - revert - tag_48: - pop mload - swap2 swap1 - pop jump\t// out + tag_55: + pop + pop + 0x00 + dup1 + revert 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 3c630bb2d6..1fa8928e1f 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/output.json @@ -72,7 +72,7 @@ sub_0: assembly { object \"C_6\" { code { /// @src 0:60:101 \"contract C {...\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -103,7 +103,7 @@ object \"C_6\" { object \"C_6_deployed\" { code { /// @src 0:60:101 \"contract C {...\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -187,11 +187,12 @@ object \"C_6\" { code { { /// @src 0:60:101 \"contract C {...\" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize(\"C_6_deployed\") - codecopy(128, dataoffset(\"C_6_deployed\"), _1) - return(128, _1) + let _2 := datasize(\"C_6_deployed\") + codecopy(_1, dataoffset(\"C_6_deployed\"), _2) + return(_1, _2) } } /// @use-src 0:\"C\" @@ -199,15 +200,16 @@ object \"C_6\" { code { { /// @src 0:60:101 \"contract C {...\" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/output.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/output.json index 1f728995dd..e427b7fe10 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/output.json @@ -72,7 +72,7 @@ sub_0: assembly { object \"C_6\" { code { /// @src 0:60:101 - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -103,7 +103,7 @@ object \"C_6\" { object \"C_6_deployed\" { code { /// @src 0:60:101 - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -186,11 +186,12 @@ object \"C_6\" { code { { /// @src 0:60:101 - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize(\"C_6_deployed\") - codecopy(128, dataoffset(\"C_6_deployed\"), _1) - return(128, _1) + let _2 := datasize(\"C_6_deployed\") + codecopy(_1, dataoffset(\"C_6_deployed\"), _2) + return(_1, _2) } } /// @use-src 0:\"C\" @@ -198,15 +199,16 @@ object \"C_6\" { code { { /// @src 0:60:101 - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/output.json b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/output.json index 8d19f60a3e..e81f461d2f 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/output.json @@ -69,7 +69,7 @@ sub_0: assembly { object \"C_6\" { code { - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_6() @@ -96,7 +96,7 @@ object \"C_6\" { object \"C_6_deployed\" { code { - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -176,26 +176,28 @@ object \"C_6\" { object \"C_6\" { code { { - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize(\"C_6_deployed\") - codecopy(128, dataoffset(\"C_6_deployed\"), _1) - return(128, _1) + let _2 := datasize(\"C_6_deployed\") + codecopy(_1, dataoffset(\"C_6_deployed\"), _2) + return(_1, _2) } } /// @use-src 0:\"C\" object \"C_6_deployed\" { code { { - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - return(128, _1) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } + return(_1, _2) } } revert(0, 0) diff --git a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json index 7a77d60f40..6a105aadde 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json @@ -10,7 +10,7 @@ object \"C_54\" { code { /// @src 0:79:435 \"contract C...\" - mstore(64, 160) + mstore(64, memoryguard(160)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } let _1 := copy_arguments_for_constructor_20_object_C_54() @@ -161,7 +161,7 @@ object \"C_54\" { object \"C_54_deployed\" { code { /// @src 0:79:435 \"contract C...\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -592,30 +592,31 @@ object \"C_54\" { code { { /// @src 0:79:435 \"contract C...\" - mstore(64, 160) + let _1 := memoryguard(0xa0) + mstore(64, _1) if callvalue() { revert(0, 0) } let programSize := datasize(\"C_54\") let argSize := sub(codesize(), programSize) - let newFreePtr := add(160, and(add(argSize, 31), not(31))) - if or(gt(newFreePtr, sub(shl(64, 1), 1)), lt(newFreePtr, 160)) + let newFreePtr := add(_1, and(add(argSize, 31), not(31))) + if or(gt(newFreePtr, sub(shl(64, 1), 1)), lt(newFreePtr, _1)) { mstore(/** @src -1:-1:-1 */ 0, /** @src 0:79:435 \"contract C...\" */ shl(224, 0x4e487b71)) mstore(4, 0x41) revert(/** @src -1:-1:-1 */ 0, /** @src 0:79:435 \"contract C...\" */ 0x24) } mstore(64, newFreePtr) - codecopy(160, programSize, argSize) - if slt(argSize, 32) + codecopy(_1, programSize, argSize) + if slt(sub(add(_1, argSize), _1), 32) { revert(/** @src -1:-1:-1 */ 0, 0) } /// @src 0:79:435 \"contract C...\" - constructor_C(mload(160)) - let _1 := mload(64) - let _2 := datasize(\"C_54_deployed\") - codecopy(_1, dataoffset(\"C_54_deployed\"), _2) - setimmutable(_1, \"8\", mload(128)) - return(_1, _2) + constructor_C(mload(_1)) + let _2 := mload(64) + let _3 := datasize(\"C_54_deployed\") + codecopy(_2, dataoffset(\"C_54_deployed\"), _3) + setimmutable(_2, \"8\", mload(128)) + return(_2, _3) } /// @ast-id 20 @src 0:182:230 \"constructor(int _init)...\" function constructor_C(var_init) @@ -631,7 +632,7 @@ object \"C_54\" { code { { /// @src 0:79:435 \"contract C...\" - mstore(64, 128) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { let _1 := 0 @@ -774,7 +775,7 @@ object \"C_54\" { object \"D_72\" { code { /// @src 1:91:166 \"contract D is C(3)...\" - mstore(64, 160) + mstore(64, memoryguard(160)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } let _1 := copy_arguments_for_constructor_71_object_D_72() @@ -993,7 +994,7 @@ object \"D_72\" { object \"D_72_deployed\" { code { /// @src 1:91:166 \"contract D is C(3)...\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -1424,30 +1425,31 @@ object \"D_72\" { code { { /// @src 1:91:166 \"contract D is C(3)...\" - mstore(64, 160) + let _1 := memoryguard(0xa0) + mstore(64, _1) if callvalue() { revert(0, 0) } let programSize := datasize(\"D_72\") let argSize := sub(codesize(), programSize) - let newFreePtr := add(160, and(add(argSize, 31), not(31))) - if or(gt(newFreePtr, sub(shl(64, 1), 1)), lt(newFreePtr, 160)) + let newFreePtr := add(_1, and(add(argSize, 31), not(31))) + if or(gt(newFreePtr, sub(shl(64, 1), 1)), lt(newFreePtr, _1)) { mstore(/** @src -1:-1:-1 */ 0, /** @src 1:91:166 \"contract D is C(3)...\" */ shl(224, 0x4e487b71)) mstore(4, 0x41) revert(/** @src -1:-1:-1 */ 0, /** @src 1:91:166 \"contract D is C(3)...\" */ 0x24) } mstore(64, newFreePtr) - codecopy(160, programSize, argSize) - if slt(argSize, 32) + codecopy(_1, programSize, argSize) + if slt(sub(add(_1, argSize), _1), 32) { revert(/** @src -1:-1:-1 */ 0, 0) } /// @src 1:91:166 \"contract D is C(3)...\" - constructor_D(mload(160)) - let _1 := mload(64) - let _2 := datasize(\"D_72_deployed\") - codecopy(_1, dataoffset(\"D_72_deployed\"), _2) - setimmutable(_1, \"8\", mload(128)) - return(_1, _2) + constructor_D(mload(_1)) + let _2 := mload(64) + let _3 := datasize(\"D_72_deployed\") + codecopy(_2, dataoffset(\"D_72_deployed\"), _3) + setimmutable(_2, \"8\", mload(128)) + return(_2, _3) } /// @ast-id 71 @src 1:113:164 \"constructor(int _init2)...\" function constructor_D(var_init2) @@ -1471,7 +1473,7 @@ object \"D_72\" { code { { /// @src 1:91:166 \"contract D is C(3)...\" - mstore(64, 128) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { let _1 := 0 diff --git a/test/cmdlineTests/standard_ewasm_requested/output.json b/test/cmdlineTests/standard_ewasm_requested/output.json index c70693bc64..a8ab1fd0bf 100644 --- a/test/cmdlineTests/standard_ewasm_requested/output.json +++ b/test/cmdlineTests/standard_ewasm_requested/output.json @@ -17,7 +17,7 @@ (local $z3 i64) (local $_1 i64) (block $label_ - (local.set $p (call $u256_to_i32_726)) + (local.set $p (call $u256_to_i32_716)) (local.set $r (i32.add (local.get $p) (i32.const 64))) (if (i32.lt_u (local.get $r) (local.get $p)) (then (unreachable))) @@ -30,14 +30,14 @@ (call $eth.getCallValue (i32.const 0)) (local.set $z3 (i64.load (i32.const 8))) (if (i32.eqz (i64.eqz (i64.or (i64.or (i64.const 0) (i64.const 0)) (i64.or (local.get $z3) (i64.load (i32.const 0)))))) (then - (call $eth.revert (call $to_internal_i32ptr) (call $u256_to_i32_344)))) + (call $eth.revert (call $to_internal_i32ptr_334) (call $u256_to_i32_333)))) (local.set $_1 (datasize \"C_3_deployed\")) - (call $eth.codeCopy (call $to_internal_i32ptr_348) (call $u256_to_i32 (dataoffset \"C_3_deployed\")) (call $u256_to_i32 (local.get $_1))) - (call $eth.finish (call $to_internal_i32ptr_348) (call $u256_to_i32 (local.get $_1))) + (call $eth.codeCopy (call $to_internal_i32ptr) (call $u256_to_i32 (dataoffset \"C_3_deployed\")) (call $u256_to_i32 (local.get $_1))) + (call $eth.finish (call $to_internal_i32ptr) (call $u256_to_i32 (local.get $_1))) ) ) -(func $u256_to_i32_344 +(func $u256_to_i32_333 (result i32) (local $v i32) (local $_1 i64) @@ -68,7 +68,7 @@ (local.get $v) ) -(func $u256_to_i32_726 +(func $u256_to_i32_716 (result i32) (local $v i32) (block $label__3 @@ -82,12 +82,12 @@ (local.get $v) ) -(func $to_internal_i32ptr +(func $to_internal_i32ptr_334 (result i32) (local $r i32) (local $p i32) (block $label__4 - (local.set $p (call $u256_to_i32_344)) + (local.set $p (call $u256_to_i32_333)) (local.set $r (i32.add (local.get $p) (i32.const 64))) (if (i32.lt_u (local.get $r) (local.get $p)) (then (unreachable))) @@ -96,7 +96,7 @@ (local.get $r) ) -(func $to_internal_i32ptr_348 +(func $to_internal_i32ptr (result i32) (local $r i32) (local $v i32) diff --git a/test/cmdlineTests/standard_irOptimized_requested/output.json b/test/cmdlineTests/standard_irOptimized_requested/output.json index 78499140c3..c56849339d 100644 --- a/test/cmdlineTests/standard_irOptimized_requested/output.json +++ b/test/cmdlineTests/standard_irOptimized_requested/output.json @@ -9,7 +9,7 @@ object \"C_7\" { code { /// @src 0:79:121 \"contract C { function f() public pure {} }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() @@ -29,7 +29,7 @@ object \"C_7\" { object \"C_7_deployed\" { code { /// @src 0:79:121 \"contract C { function f() public pure {} }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { let selector := shift_right_224_unsigned(calldataload(0)) diff --git a/test/cmdlineTests/standard_ir_requested/output.json b/test/cmdlineTests/standard_ir_requested/output.json index 2da612abc6..59f07f768c 100644 --- a/test/cmdlineTests/standard_ir_requested/output.json +++ b/test/cmdlineTests/standard_ir_requested/output.json @@ -10,7 +10,7 @@ object \"C_7\" { code { /// @src 0:79:121 \"contract C { function f() public pure {} }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_7() @@ -41,7 +41,7 @@ object \"C_7\" { object \"C_7_deployed\" { code { /// @src 0:79:121 \"contract C { function f() public pure {} }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/standard_viair_requested/output.json b/test/cmdlineTests/standard_viair_requested/output.json index 4bf34fd7af..b72923f484 100644 --- a/test/cmdlineTests/standard_viair_requested/output.json +++ b/test/cmdlineTests/standard_viair_requested/output.json @@ -10,7 +10,7 @@ object \"C_3\" { code { /// @src 0:79:92 \"contract C {}\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_3() @@ -41,7 +41,7 @@ object \"C_3\" { object \"C_3_deployed\" { code { /// @src 0:79:92 \"contract C {}\" - mstore(64, 128) + mstore(64, memoryguard(128)) revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() @@ -79,7 +79,7 @@ object \"C_3\" { object \"D_16\" { code { /// @src 0:93:146 \"contract D { function f() public { C c = new C(); } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_D_16() @@ -110,7 +110,7 @@ object \"D_16\" { object \"D_16_deployed\" { code { /// @src 0:93:146 \"contract D { function f() public { C c = new C(); } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { @@ -212,7 +212,7 @@ object \"D_16\" { object \"C_3\" { code { /// @src 0:79:92 \"contract C {}\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_3() @@ -243,7 +243,7 @@ object \"D_16\" { object \"C_3_deployed\" { code { /// @src 0:79:92 \"contract C {}\" - mstore(64, 128) + mstore(64, memoryguard(128)) revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() diff --git a/test/cmdlineTests/standard_yul_optimiserSteps/output.json b/test/cmdlineTests/standard_yul_optimiserSteps/output.json index 3caeed8dbf..4071589cbe 100644 --- a/test/cmdlineTests/standard_yul_optimiserSteps/output.json +++ b/test/cmdlineTests/standard_yul_optimiserSteps/output.json @@ -1,10 +1,12 @@ -{"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":17:18 */ +{"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":38:39 */ 0x00 /* \"A\":11:19 */ dup1 mload /* \"A\":20:40 */ sstore + /* \"A\":0:42 */ + stop ","bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""}},"ir":"object \"object\" { code { let x := mload(0) diff --git a/test/cmdlineTests/standard_yul_optimized/output.json b/test/cmdlineTests/standard_yul_optimized/output.json index a5217c6729..371a0816b6 100644 --- a/test/cmdlineTests/standard_yul_optimized/output.json +++ b/test/cmdlineTests/standard_yul_optimized/output.json @@ -1,10 +1,12 @@ {"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":17:18 */ 0x00 - dup1 /* \"A\":11:19 */ + dup1 mload /* \"A\":20:40 */ sstore + /* \"A\":0:42 */ + stop ","bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""}},"ir":"object \"object\" { code { let x := mload(0) diff --git a/test/cmdlineTests/standard_yul_stack_opt/output.json b/test/cmdlineTests/standard_yul_stack_opt/output.json index 0fd77310ed..f041adaa86 100644 --- a/test/cmdlineTests/standard_yul_stack_opt/output.json +++ b/test/cmdlineTests/standard_yul_stack_opt/output.json @@ -1,17 +1,15 @@ {"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":16:17 */ 0x01 - dup1 /* \"A\":27:28 */ 0x00 /* \"A\":20:32 */ sstore - pop /* \"A\":50:51 */ 0x02 - dup1 /* \"A\":61:63 */ 0x20 /* \"A\":54:67 */ sstore - pop + /* \"A\":0:72 */ + stop "}}}},"errors":[{"component":"general","formattedMessage":"Yul is still experimental. Please use the output with care.","message":"Yul is still experimental. Please use the output with care.","severity":"warning","type":"Warning"}]} diff --git a/test/cmdlineTests/strict_asm_optimizer_steps/output b/test/cmdlineTests/strict_asm_optimizer_steps/output index bf9f34e7a4..0f7a59b977 100644 --- a/test/cmdlineTests/strict_asm_optimizer_steps/output +++ b/test/cmdlineTests/strict_asm_optimizer_steps/output @@ -25,7 +25,7 @@ object "C_6" { Binary representation: -60806040523415600e57600080fd5b600e601c600039600e6000f3fe60806040523615600055600080fd +608060405234601557600e601b600039600e6000f35b600080fdfe60806040523615600055600080fd Text representation: /* "strict_asm_optimizer_steps/input.yul":45:48 */ @@ -37,17 +37,8 @@ Text representation: /* "strict_asm_optimizer_steps/input.yul":61:72 */ callvalue /* "strict_asm_optimizer_steps/input.yul":58:89 */ - iszero tag_1 jumpi - /* "strict_asm_optimizer_steps/input.yul":85:86 */ - 0x00 - /* "strict_asm_optimizer_steps/input.yul":82:83 */ - dup1 - /* "strict_asm_optimizer_steps/input.yul":75:87 */ - revert - /* "strict_asm_optimizer_steps/input.yul":58:89 */ -tag_1: /* "strict_asm_optimizer_steps/input.yul":138:162 */ dataSize(sub_0) /* "strict_asm_optimizer_steps/input.yul":110:136 */ @@ -62,6 +53,13 @@ tag_1: 0x00 /* "strict_asm_optimizer_steps/input.yul":172:207 */ return + /* "strict_asm_optimizer_steps/input.yul":73:89 */ +tag_1: + /* "strict_asm_optimizer_steps/input.yul":85:86 */ + 0x00 + /* "strict_asm_optimizer_steps/input.yul":75:87 */ + dup1 + revert stop sub_0: assembly { @@ -81,8 +79,7 @@ sub_0: assembly { sstore /* "strict_asm_optimizer_steps/input.yul":576:577 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":573:574 */ - dup1 /* "strict_asm_optimizer_steps/input.yul":566:578 */ + dup1 revert } diff --git a/test/cmdlineTests/viair_abicoder_v1/output b/test/cmdlineTests/viair_abicoder_v1/output index a23730702e..cedda56dcc 100644 --- a/test/cmdlineTests/viair_abicoder_v1/output +++ b/test/cmdlineTests/viair_abicoder_v1/output @@ -11,7 +11,7 @@ IR: object "test_11" { code { /// @src 0:79:169 "contract test {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_test_11() @@ -42,7 +42,7 @@ object "test_11" { object "test_11_deployed" { code { /// @src 0:79:169 "contract test {..." - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/viair_subobjects/output b/test/cmdlineTests/viair_subobjects/output index eef7d27e86..4b388665cf 100644 --- a/test/cmdlineTests/viair_subobjects/output +++ b/test/cmdlineTests/viair_subobjects/output @@ -17,11 +17,12 @@ object "C_3" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_3_deployed") - codecopy(128, dataoffset("C_3_deployed"), _1) - return(128, _1) + let _2 := datasize("C_3_deployed") + codecopy(_1, dataoffset("C_3_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"viair_subobjects/input.sol" @@ -29,7 +30,7 @@ object "C_3" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } @@ -56,11 +57,12 @@ object "D_16" { code { { /// @src 0:96:165 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("D_16_deployed") - codecopy(128, dataoffset("D_16_deployed"), _1) - return(128, _1) + let _2 := datasize("D_16_deployed") + codecopy(_1, dataoffset("D_16_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"viair_subobjects/input.sol" @@ -68,35 +70,35 @@ object "D_16" { code { { /// @src 0:96:165 "contract D {..." - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0x26121ff0, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0x26121ff0, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - /// @src 0:149:156 "new C()" - let _2 := datasize("C_3") - let _3 := add(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ _2) - if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:96:165 "contract D {..." */ 128)) + if callvalue() { revert(_2, _2) } + if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) } /// @src 0:149:156 "new C()" + let _3 := datasize("C_3") + let _4 := add(_1, _3) + if or(gt(_4, 0xffffffffffffffff), lt(_4, _1)) { /// @src 0:96:165 "contract D {..." - mstore(_1, shl(224, 0x4e487b71)) + mstore(_2, shl(224, 0x4e487b71)) mstore(4, 0x41) - revert(_1, 0x24) + revert(_2, 0x24) } /// @src 0:149:156 "new C()" - datacopy(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ dataoffset("C_3"), _2) - if iszero(create(/** @src 0:96:165 "contract D {..." */ _1, 128, /** @src 0:149:156 "new C()" */ _2)) + datacopy(_1, dataoffset("C_3"), _3) + if iszero(create(/** @src 0:96:165 "contract D {..." */ _2, /** @src 0:149:156 "new C()" */ _1, sub(_4, _1))) { /// @src 0:96:165 "contract D {..." let pos := mload(64) - returndatacopy(pos, _1, returndatasize()) + returndatacopy(pos, _2, returndatasize()) revert(pos, returndatasize()) } - return(mload(64), _1) + return(mload(64), _2) } } revert(0, 0) @@ -107,11 +109,12 @@ object "D_16" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + let _1 := memoryguard(0x80) + mstore(64, _1) if callvalue() { revert(0, 0) } - let _1 := datasize("C_3_deployed") - codecopy(128, dataoffset("C_3_deployed"), _1) - return(128, _1) + let _2 := datasize("C_3_deployed") + codecopy(_1, dataoffset("C_3_deployed"), _2) + return(_1, _2) } } /// @use-src 0:"viair_subobjects/input.sol" @@ -119,7 +122,7 @@ object "D_16" { code { { /// @src 0:82:95 "contract C {}" - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert(0, 0) } } diff --git a/test/cmdlineTests/yul_optimize_runs/output b/test/cmdlineTests/yul_optimize_runs/output index 4c98ec30eb..b95184440d 100644 --- a/test/cmdlineTests/yul_optimize_runs/output +++ b/test/cmdlineTests/yul_optimize_runs/output @@ -21,20 +21,18 @@ object "RunsTest1" { Binary representation: -602480600d600039806000f3fe7fabc1234500000000000000000000000000000000000000000000000000000000600055 +602580600c6000396000f3fe7fabc123450000000000000000000000000000000000000000000000000000000060005500 Text representation: /* "yul_optimize_runs/input.yul":106:125 */ dataSize(sub_0) - dup1 /* "yul_optimize_runs/input.yul":83:104 */ + dup1 dataOffset(sub_0) /* "yul_optimize_runs/input.yul":80:81 */ 0x00 /* "yul_optimize_runs/input.yul":71:126 */ codecopy - /* "yul_optimize_runs/input.yul":145:164 */ - dup1 /* "yul_optimize_runs/input.yul":80:81 */ 0x00 /* "yul_optimize_runs/input.yul":135:165 */ @@ -48,4 +46,6 @@ sub_0: assembly { 0x00 /* "yul_optimize_runs/input.yul":270:288 */ sstore + /* "yul_optimize_runs/input.yul":208:298 */ + stop } diff --git a/test/cmdlineTests/yul_optimizer_steps/output b/test/cmdlineTests/yul_optimizer_steps/output index 8e4cc7e88f..a88ce164ac 100644 --- a/test/cmdlineTests/yul_optimizer_steps/output +++ b/test/cmdlineTests/yul_optimizer_steps/output @@ -11,7 +11,7 @@ object "C_7" { code { { /// @src 0:80:112 "contract C..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() @@ -30,7 +30,7 @@ object "C_7" { code { { /// @src 0:80:112 "contract C..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() } function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() diff --git a/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output b/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output index 63f08a35dd..cc67ca5bcb 100644 --- a/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output +++ b/test/cmdlineTests/yul_optimizer_steps_nested_brackets/output @@ -11,7 +11,7 @@ object "C_6" { code { { /// @src 0:60:103 "contract C..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() @@ -121,7 +121,7 @@ object "C_6" { code { { /// @src 0:60:103 "contract C..." - mstore(64, 128) + mstore(64, memoryguard(0x80)) if iszero(lt(calldatasize(), 4)) { let selector := shift_right_unsigned(calldataload(0)) diff --git a/test/cmdlineTests/yul_string_format_ascii/output.json b/test/cmdlineTests/yul_string_format_ascii/output.json index ae7a926fe7..2354929e40 100644 --- a/test/cmdlineTests/yul_string_format_ascii/output.json +++ b/test/cmdlineTests/yul_string_format_ascii/output.json @@ -10,7 +10,7 @@ object \"C_11\" { code { /// @src 0:78:164 \"contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_11() @@ -41,7 +41,7 @@ object \"C_11\" { object \"C_11_deployed\" { code { /// @src 0:78:164 \"contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json index 59a93a7bfe..84e9ff2713 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json @@ -10,7 +10,7 @@ object \"C_11\" { code { /// @src 0:78:158 \"contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_11() @@ -41,7 +41,7 @@ object \"C_11\" { object \"C_11_deployed\" { code { /// @src 0:78:158 \"contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json index 79d35a3389..716a1cc6e6 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json @@ -10,7 +10,7 @@ object \"C_11\" { code { /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_11() @@ -41,7 +41,7 @@ object \"C_11\" { object \"C_11_deployed\" { code { /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_string_format_ascii_long/output.json b/test/cmdlineTests/yul_string_format_ascii_long/output.json index 932a5c28ca..1f52e103be 100644 --- a/test/cmdlineTests/yul_string_format_ascii_long/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_long/output.json @@ -10,7 +10,7 @@ object \"C_11\" { code { /// @src 0:78:243 \"contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_11() @@ -41,7 +41,7 @@ object \"C_11\" { object \"C_11_deployed\" { code { /// @src 0:78:243 \"contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_string_format_hex/output.json b/test/cmdlineTests/yul_string_format_hex/output.json index da8f873a31..04166a7601 100644 --- a/test/cmdlineTests/yul_string_format_hex/output.json +++ b/test/cmdlineTests/yul_string_format_hex/output.json @@ -10,7 +10,7 @@ object \"C_11\" { code { /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } constructor_C_11() @@ -41,7 +41,7 @@ object \"C_11\" { object \"C_11_deployed\" { code { /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\" - mstore(64, 128) + mstore(64, memoryguard(128)) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_verbatim_msize/output b/test/cmdlineTests/yul_verbatim_msize/output index 5f67aa85ec..991fcbdb0c 100644 --- a/test/cmdlineTests/yul_verbatim_msize/output +++ b/test/cmdlineTests/yul_verbatim_msize/output @@ -14,7 +14,7 @@ object "object" { Binary representation: -612000515061616002600055 +61200051506161600260005500 Text representation: /* "yul_verbatim_msize/input.yul":125:131 */ @@ -30,3 +30,5 @@ Text representation: 0x00 /* "yul_verbatim_msize/input.yul":162:174 */ sstore + /* "yul_verbatim_msize/input.yul":0:176 */ + stop diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol index 4161cb7d84..06f9bcbbfc 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol @@ -24,6 +24,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb -// gas irOptimized: 203522 +// gas irOptimized: 203312 // gas legacy: 206084 // gas legacyOptimized: 203068 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index 61b8f38103..ddd536a380 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -60,10 +60,10 @@ contract C { // compileViaYul: also // ---- // test_bytes() -> -// gas irOptimized: 394829 +// gas irOptimized: 377545 // gas legacy: 423563 // gas legacyOptimized: 331391 // test_uint256() -> -// gas irOptimized: 553331 +// gas irOptimized: 528726 // gas legacy: 591392 // gas legacyOptimized: 456137 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol index 458c11893f..8fe170e917 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -26,6 +26,6 @@ contract C { // ---- // library: L // f() -> 8, 7, 1, 2, 7, 12 -// gas irOptimized: 167615 +// gas irOptimized: 167580 // gas legacy: 169475 // gas legacyOptimized: 167397 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index 7b7854c230..3a4a23fef7 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -61,10 +61,10 @@ contract C { // compileViaYul: also // ---- // test_bytes() -> -// gas irOptimized: 394829 +// gas irOptimized: 377545 // gas legacy: 423563 // gas legacyOptimized: 331391 // test_uint256() -> -// gas irOptimized: 553331 +// gas irOptimized: 528726 // gas legacy: 591392 // gas legacyOptimized: 456137 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol index d475ffa19f..3e96976981 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol @@ -53,6 +53,6 @@ contract C { // f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" // f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" // f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, "abc", 0x7, 0x40, 0x2, 0x2, 0x3 -// gas irOptimized: 113296 +// gas irOptimized: 113361 // gas legacy: 114900 // gas legacyOptimized: 112606 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol index bf57dbe6f2..b730f3588d 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol @@ -32,6 +32,6 @@ contract C is B { // compileViaYul: also // ---- // test() -> 77 -// gas irOptimized: 121699 +// gas irOptimized: 120044 // gas legacy: 155221 // gas legacyOptimized: 111678 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol index 7fceb59352..7832ef601e 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol @@ -40,5 +40,5 @@ contract C is B { // compileViaYul: also // ---- // test() -> 5, 10 -// gas irOptimized: 88225 +// gas irOptimized: 87578 // gas legacy: 99137 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index 2841ef243d..bf42f87761 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -21,6 +21,6 @@ contract C { // f(uint256[][1]): 32, 32, 0 -> true // f(uint256[][1]): 32, 32, 1, 42 -> true // f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true -// gas irOptimized: 177581 +// gas irOptimized: 172204 // gas legacy: 141900 // gas legacyOptimized: 121788 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol index 12f12ef29c..1f836bfafa 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol @@ -19,10 +19,10 @@ contract C { // compileViaYul: also // ---- // h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324 -// gas irOptimized: 181123 +// gas irOptimized: 180925 // gas legacy: 184929 // gas legacyOptimized: 181504 // i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224 -// gas irOptimized: 112627 +// gas irOptimized: 112535 // gas legacy: 115468 // gas legacyOptimized: 112988 diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol index cbdaa381f3..b6c6ad5f03 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol @@ -11,6 +11,6 @@ contract C { // compileViaYul: also // ---- // f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" -// gas irOptimized: 135996 +// gas irOptimized: 135918 // gas legacy: 137190 // gas legacyOptimized: 136082 diff --git a/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol b/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol index 596e76a669..e8d5670598 100644 --- a/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol @@ -14,7 +14,7 @@ contract Test { // compileViaYul: also // ---- // set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06 -// gas irOptimized: 189239 +// gas irOptimized: 189910 // gas legacy: 211149 // gas legacyOptimized: 206054 // data(uint256,uint256): 0x02, 0x02 -> 0x09 diff --git a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol index 2514896605..2c238a54b0 100644 --- a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol +++ b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol @@ -47,7 +47,7 @@ contract c { // gas legacyOptimized: 58606 // storageEmpty -> 0 // test_long() -> 67 -// gas irOptimized: 90759 +// gas irOptimized: 89148 // gas legacy: 103590 // gas legacyOptimized: 101044 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol index a4403c3d7f..31879057a7 100644 --- a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol +++ b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol @@ -19,6 +19,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0 -// gas irOptimized: 165224 +// gas irOptimized: 158143 // gas legacy: 189715 // gas legacyOptimized: 184472 diff --git a/test/libsolidity/semanticTests/array/bytes_length_member.sol b/test/libsolidity/semanticTests/array/bytes_length_member.sol index aaf990ef68..bb4e21e16f 100644 --- a/test/libsolidity/semanticTests/array/bytes_length_member.sol +++ b/test/libsolidity/semanticTests/array/bytes_length_member.sol @@ -15,7 +15,7 @@ contract c { // ---- // getLength() -> 0 // set(): 1, 2 -> true -// gas irOptimized: 110439 +// gas irOptimized: 110433 // gas legacy: 110726 // gas legacyOptimized: 110567 // getLength() -> 68 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol index 4795624b41..2a401cd87d 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol @@ -22,7 +22,7 @@ contract c { // compileViaYul: also // ---- // store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32 -// gas irOptimized: 650971 +// gas irOptimized: 650669 // gas legacy: 694515 // gas legacyOptimized: 694013 // retrieve() -> 9, 28, 9, 28, 4, 3, 32 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol index 91ae6913f8..3449cdc2d8 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol @@ -23,6 +23,6 @@ contract C { // compileViaYul: also // ---- // f() -> true -// gas irOptimized: 92843 +// gas irOptimized: 92740 // gas legacy: 93035 // gas legacyOptimized: 92257 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol index 2b74d52e46..73abd2cf7a 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol @@ -48,6 +48,6 @@ contract C { // compileViaYul: also // ---- // f() -> true -// gas irOptimized: 153927 +// gas irOptimized: 153260 // gas legacy: 155961 // gas legacyOptimized: 153588 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol index f8dea7bbec..e90cf7e58f 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0 -// gas irOptimized: 135145 +// gas irOptimized: 135098 // gas legacy: 135313 // gas legacyOptimized: 134548 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol index b9e80c1d71..bd596b86c2 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol @@ -42,11 +42,11 @@ contract C { // compileViaYul: also // ---- // f() -> 0 -// gas irOptimized: 92855 +// gas irOptimized: 92800 // gas legacy: 93006 // gas legacyOptimized: 92261 // g() -> 0 // h() -> 0 -// gas irOptimized: 92922 +// gas irOptimized: 92862 // gas legacy: 93028 // gas legacyOptimized: 92303 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol index 1cfbd17332..81607a2643 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol @@ -21,6 +21,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000 -// gas irOptimized: 212669 +// gas irOptimized: 212571 // gas legacy: 221883 // gas legacyOptimized: 220734 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol index 2a58b92569..4f70232509 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol @@ -37,12 +37,12 @@ contract c { // compileViaYul: also // ---- // test() -> 0x02000202 -// gas irOptimized: 4660920 +// gas irOptimized: 4652092 // gas legacy: 4578341 // gas legacyOptimized: 4548354 // storageEmpty -> 1 // clear() -> 0, 0 -// gas irOptimized: 4491908 +// gas irOptimized: 4483169 // gas legacy: 4410769 // gas legacyOptimized: 4382531 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol b/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol index deb9404e35..0e05c4ea8e 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol @@ -15,6 +15,6 @@ contract c { // compileViaYul: also // ---- // test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10 -// gas irOptimized: 690506 +// gas irOptimized: 690205 // gas legacy: 686268 // gas legacyOptimized: 685688 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol index cee96209a7..cad3c9d492 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol @@ -19,6 +19,6 @@ contract c { // compileViaYul: also // ---- // test() -> 5, 4 -// gas irOptimized: 226130 +// gas irOptimized: 225956 // gas legacy: 233801 // gas legacyOptimized: 232816 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol index fcec284cc7..4a475ac559 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol @@ -24,6 +24,6 @@ contract c { // compileViaYul: also // ---- // test() -> 3, 4 -// gas irOptimized: 190944 +// gas irOptimized: 190480 // gas legacy: 195353 // gas legacyOptimized: 192441 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol index 05e0383784..202b3ad264 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol @@ -17,7 +17,7 @@ contract c { // ---- // setData1(uint256,uint256,uint256): 10, 5, 4 -> // copyStorageStorage() -> -// gas irOptimized: 111488 +// gas irOptimized: 111426 // gas legacy: 109278 // gas legacyOptimized: 109268 // getData2(uint256): 5 -> 10, 4 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol index 167e2740e2..3b8fe6212a 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol @@ -20,6 +20,6 @@ contract c { // compileViaYul: also // ---- // test() -> 5, 4 -// gas irOptimized: 272806 +// gas irOptimized: 272736 // gas legacy: 270834 // gas legacyOptimized: 269960 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol index 3b2ddbde11..d2d7f4e486 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol @@ -14,6 +14,6 @@ contract c { // compileViaYul: also // ---- // test() -> 9, 4 -// gas irOptimized: 123172 +// gas irOptimized: 123162 // gas legacy: 123579 // gas legacyOptimized: 123208 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol index 8d438013a5..c865b82280 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test() -> 8, 0 -// gas irOptimized: 236016 +// gas irOptimized: 236090 // gas legacy: 234695 // gas legacyOptimized: 234103 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol index 35776b6a1f..db26b4d472 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol @@ -19,7 +19,7 @@ contract c { // compileViaYul: also // ---- // test() -> 4, 5 -// gas irOptimized: 239134 +// gas irOptimized: 238826 // gas legacy: 238736 // gas legacyOptimized: 237159 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol index 62f1ee7155..3b2815526b 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol @@ -17,6 +17,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3 -// gas irOptimized: 161746 +// gas irOptimized: 161780 // gas legacy: 162278 // gas legacyOptimized: 159955 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol index 537924f14e..1daa061a52 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol @@ -20,6 +20,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 132180 +// gas irOptimized: 129167 // gas legacy: 186406 // gas legacyOptimized: 166126 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol index 36b387971e..b42b84dfe7 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0 -// gas irOptimized: 93855 +// gas irOptimized: 93858 // gas legacy: 97451 // gas legacyOptimized: 94200 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol index b0387042f7..c87f70244c 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0 -// gas irOptimized: 294958 +// gas irOptimized: 294772 // gas legacy: 303653 // gas legacyOptimized: 301999 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol index 893fbdba3b..c39f802757 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00 -// gas irOptimized: 274022 +// gas irOptimized: 273963 // gas legacy: 276381 // gas legacyOptimized: 275453 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol index 78f1bef9f9..3cc9c9bd9f 100644 --- a/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol @@ -38,10 +38,10 @@ contract c { // compileViaYul: true // ---- // test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65 -// gas irOptimized: 181755 +// gas irOptimized: 181308 // test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65 -// gas irOptimized: 158111 +// gas irOptimized: 157901 // test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65 -// gas irOptimized: 135282 +// gas irOptimized: 135108 // test4(uint256[2][2]): 23, 42, 23, 42 -> 65 -// gas irOptimized: 111460 +// gas irOptimized: 111428 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol index 707e250564..826d48b2ba 100644 --- a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol @@ -40,12 +40,12 @@ contract Test { // compileViaYul: also // ---- // test() -> 24 -// gas irOptimized: 227254 +// gas irOptimized: 227167 // gas legacy: 227133 // gas legacyOptimized: 226547 // test1() -> 3 // test2() -> 6 // test3() -> 24 -// gas irOptimized: 133753 +// gas irOptimized: 133621 // gas legacy: 134295 // gas legacyOptimized: 133383 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol index 27f81692c9..b3d950ffa8 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol @@ -17,4 +17,4 @@ contract C { // compileViaYul: true // ---- // f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12 -// gas irOptimized: 121194 +// gas irOptimized: 121048 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol index 6f11f6c662..2fe2715876 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol @@ -19,4 +19,4 @@ contract C { // compileViaYul: true // ---- // f() -> 10, 11, 12 -// gas irOptimized: 119201 +// gas irOptimized: 119149 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol index 970a5dcedf..7d4e1f845f 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol @@ -23,4 +23,4 @@ contract C { // compileViaYul: true // ---- // f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1 -// gas irOptimized: 330385 +// gas irOptimized: 328592 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol index e4ff169f42..0b1d71bdf2 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol @@ -26,4 +26,4 @@ contract C { // compileViaYul: true // ---- // f() -> 3, 3, 3, 1 -// gas irOptimized: 183411 +// gas irOptimized: 183316 diff --git a/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol b/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol index e23efb6660..de38034fd3 100644 --- a/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol +++ b/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> 1, 2, 3 -// gas irOptimized: 132580 +// gas irOptimized: 132298 // gas legacy: 134619 // gas legacyOptimized: 131940 diff --git a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol index cee56c23bd..dadbceadcb 100644 --- a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol @@ -12,7 +12,7 @@ contract Test { // compileViaYul: also // ---- // set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18 -// gas irOptimized: 99873 +// gas irOptimized: 99616 // gas legacy: 103563 // gas legacyOptimized: 101397 // data(uint256): 7 -> 8 diff --git a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol index dd5f2a86ae..809ef247d5 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol @@ -7,11 +7,11 @@ contract c { // compileViaYul: also // ---- // set(uint256): 1, 2 -> true -// gas irOptimized: 110678 +// gas irOptimized: 110699 // gas legacy: 111091 // gas legacyOptimized: 110736 // set(uint256): 2, 2, 3, 4, 5 -> true -// gas irOptimized: 177635 +// gas irOptimized: 177659 // gas legacy: 178021 // gas legacyOptimized: 177666 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol index fb4e2159d8..87974f053a 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol @@ -19,25 +19,25 @@ contract c { // ---- // f(uint256): 0 -> 0x20, 0x00 // f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 -// gas irOptimized: 125470 +// gas irOptimized: 121741 // gas legacy: 124364 // gas legacyOptimized: 119898 // f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 -// gas irOptimized: 134121 +// gas irOptimized: 130733 // gas legacy: 135431 // gas legacyOptimized: 130829 // f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 141217 +// gas irOptimized: 137732 // gas legacy: 142238 // gas legacyOptimized: 137518 // f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992 -// gas irOptimized: 158957 +// gas irOptimized: 152352 // gas legacy: 160728 // gas legacyOptimized: 152168 // f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 // gas legacy: 59345 // gas legacyOptimized: 57279 // f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 -// gas irOptimized: 419485 +// gas irOptimized: 406089 // gas legacy: 423017 // gas legacyOptimized: 406021 diff --git a/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol b/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol index 7fba61c2ce..7c0b3bdbbd 100644 --- a/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol @@ -11,6 +11,6 @@ contract C { // compileViaYul: also // ---- // f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1 -// gas irOptimized: 111204 +// gas irOptimized: 111161 // gas legacy: 111565 // gas legacyOptimized: 111347 diff --git a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol index 6bb47d9d98..ed0fe8f5f4 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol @@ -37,11 +37,11 @@ contract C { // compileViaYul: also // ---- // f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000 -// gas irOptimized: 179947 +// gas irOptimized: 179952 // gas legacy: 180694 // gas legacyOptimized: 180088 // g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000 -// gas irOptimized: 107322 +// gas irOptimized: 107332 // gas legacy: 107895 // gas legacyOptimized: 107254 // h() -> 0x40, 0x60, 0x00, 0x00 diff --git a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol index 26332e6f2a..b73f3dc448 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol @@ -48,6 +48,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0xff -// gas irOptimized: 121438 +// gas irOptimized: 121145 // gas legacy: 128035 // gas legacyOptimized: 123476 diff --git a/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol b/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol index 2401d90d9f..8448d2e69b 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol @@ -18,6 +18,6 @@ contract C { // compileViaYul: also // ---- // test() -> 7 -// gas irOptimized: 126212 +// gas irOptimized: 126552 // gas legacy: 205196 // gas legacyOptimized: 204987 diff --git a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol index 2532c04af2..b8ec0d97f2 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol @@ -9,7 +9,7 @@ contract c { // compileViaYul: also // ---- // set(): 1, 2, 3, 4, 5 -> true -// gas irOptimized: 177396 +// gas irOptimized: 177417 // gas legacy: 177656 // gas legacyOptimized: 177496 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol index 5cb657afec..3d4623b79d 100644 --- a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol @@ -20,6 +20,6 @@ contract C { // compileViaYul: also // ---- // f() -> 3 -// gas irOptimized: 131095 +// gas irOptimized: 129916 // gas legacy: 130307 // gas legacyOptimized: 129363 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol index 9f325200d1..ec58360cd8 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol @@ -19,6 +19,6 @@ contract C { // compileViaYul: also // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 -// gas irOptimized: 207030 +// gas irOptimized: 207785 // gas legacy: 212325 // gas legacyOptimized: 211486 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol index 5749e3ad8b..f94b442f36 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol @@ -13,6 +13,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000 -// gas irOptimized: 202750 +// gas irOptimized: 202840 // gas legacy: 204459 // gas legacyOptimized: 203437 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol index 8893bd94d4..ece6f7969f 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol @@ -20,6 +20,6 @@ contract C { // compileViaYul: also // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 -// gas irOptimized: 207030 +// gas irOptimized: 207785 // gas legacy: 212330 // gas legacyOptimized: 211491 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol index 2e1a2cc3c5..556fb5a61b 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol @@ -26,6 +26,6 @@ contract C { // compileViaYul: also // ---- // f() -> 11, 0x0c, 1, 0x15, 22, 4 -// gas irOptimized: 291923 +// gas irOptimized: 291850 // gas legacy: 293516 // gas legacyOptimized: 290263 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol index caf1e1dfd4..abcd72ee10 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> 2, 3, 4 -// gas irOptimized: 114568 +// gas irOptimized: 114120 // gas legacy: 126449 // gas legacyOptimized: 120902 diff --git a/test/libsolidity/semanticTests/array/create_memory_array.sol b/test/libsolidity/semanticTests/array/create_memory_array.sol index adc51585a7..8072526abc 100644 --- a/test/libsolidity/semanticTests/array/create_memory_array.sol +++ b/test/libsolidity/semanticTests/array/create_memory_array.sol @@ -20,6 +20,6 @@ contract C { // compileViaYul: also // ---- // f() -> "A", 8, 4, "B" -// gas irOptimized: 140716 +// gas irOptimized: 130594 // gas legacy: 121398 // gas legacyOptimized: 115494 diff --git a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol index f3c4a87b47..149e8768d7 100644 --- a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol +++ b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test1() -> true -// gas irOptimized: 230748 +// gas irOptimized: 225894 // gas legacy: 255577 // gas legacyOptimized: 248611 diff --git a/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol b/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol index 36a2eca416..82c8d6b6cc 100644 --- a/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol +++ b/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol @@ -16,4 +16,4 @@ contract C { // compileViaYul: also // ---- // f() -> 0, 0, 0 -// gas irOptimized: 91245 +// gas irOptimized: 91098 diff --git a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol index 46e3606ba0..9f4be21192 100644 --- a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol @@ -16,7 +16,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> -// gas irOptimized: 520360 +// gas irOptimized: 519848 // gas legacy: 521773 // gas legacyOptimized: 517048 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol b/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol index f95a93a223..2587442d59 100644 --- a/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol +++ b/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol @@ -44,7 +44,7 @@ contract c { // ---- // getLengths() -> 0, 0 // setLengths(uint256,uint256): 48, 49 -> -// gas irOptimized: 104851 +// gas irOptimized: 104355 // gas legacy: 108571 // gas legacyOptimized: 100417 // getLengths() -> 48, 49 diff --git a/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol index 7d7f4188b3..6aecbde32d 100644 --- a/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol @@ -18,7 +18,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> 8 -// gas irOptimized: 123113 +// gas irOptimized: 122528 // gas legacy: 121756 // gas legacyOptimized: 120687 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol index c5a63fa3a2..dd131f287f 100644 --- a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol @@ -13,7 +13,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> -// gas irOptimized: 465690 +// gas irOptimized: 465585 // gas legacy: 471460 // gas legacyOptimized: 467520 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol index ab9ae16406..5e30621af2 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol @@ -21,6 +21,6 @@ contract B { // compileViaYul: also // ---- // f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004 -// gas irOptimized: 120848 +// gas irOptimized: 130328 // gas legacy: 235199 // gas legacyOptimized: 133119 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index 6545dc9002..95cb52f112 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -45,6 +45,6 @@ contract C { // compileViaYul: also // ---- // test() -> 5, 6, 7 -// gas irOptimized: 297690 +// gas irOptimized: 302321 // gas legacy: 462080 // gas legacyOptimized: 294938 diff --git a/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol b/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol index 9788b61368..f2a98f9938 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol @@ -25,7 +25,7 @@ contract c { // compileViaYul: also // ---- // test() -> 1, 2, 3 -// gas irOptimized: 2272395 +// gas irOptimized: 2271482 // gas legacy: 2273722 // gas legacyOptimized: 2262396 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol b/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol index 3ad0d8f32f..4be29a15d3 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol @@ -20,7 +20,7 @@ contract c { // compileViaYul: also // ---- // test() -> 38, 28, 18 -// gas irOptimized: 192323 +// gas irOptimized: 188649 // gas legacy: 189780 // gas legacyOptimized: 178870 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol b/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol index dc3b2a8616..08a4031745 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol @@ -20,7 +20,7 @@ contract c { // compileViaYul: also // ---- // test() -> 20, 10 -// gas irOptimized: 161105 +// gas irOptimized: 159175 // gas legacy: 159459 // gas legacyOptimized: 153281 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol index 2b893c668a..387d21872c 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol @@ -12,6 +12,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x20, 29, 0x0303030303030303030303030303030303030303030303030303030303000000 -// gas irOptimized: 111157 +// gas irOptimized: 109503 // gas legacy: 127309 // gas legacyOptimized: 124136 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol index bf605984b0..c911b1b7c3 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol @@ -18,7 +18,7 @@ contract c { // compileViaYul: also // ---- // test() -> true -// gas irOptimized: 205254 +// gas irOptimized: 196545 // gas legacy: 229864 // gas legacyOptimized: 210964 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol index 09e65f0c57..38c0c84d63 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol @@ -17,7 +17,7 @@ contract c { // compileViaYul: also // ---- // test() -> -// gas irOptimized: 146450 +// gas irOptimized: 142640 // gas legacy: 165363 // gas legacyOptimized: 159446 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol index ca59097221..6d314fb27e 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol @@ -12,6 +12,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 109314 +// gas irOptimized: 108493 // gas legacy: 126187 // gas legacyOptimized: 123261 diff --git a/test/libsolidity/semanticTests/array/push/array_push.sol b/test/libsolidity/semanticTests/array/push/array_push.sol index 83cceeb56b..e8ec366391 100644 --- a/test/libsolidity/semanticTests/array/push/array_push.sol +++ b/test/libsolidity/semanticTests/array/push/array_push.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test() -> 5, 4, 3, 3 -// gas irOptimized: 111289 +// gas irOptimized: 111317 // gas legacy: 111838 // gas legacyOptimized: 111128 diff --git a/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol b/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol index 39f99a9bd7..a4be5ad901 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol @@ -14,6 +14,6 @@ contract C { // compileViaYul: also // ---- // f(uint120[]): 0x20, 3, 1, 2, 3 -> 1 -// gas irOptimized: 113393 +// gas irOptimized: 113267 // gas legacy: 113686 // gas legacyOptimized: 113499 diff --git a/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol b/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol index 72ab9ea148..04f9544a91 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol @@ -16,6 +16,6 @@ contract c { // compileViaYul: also // ---- // test() -> 1, 2, 3, 4 -// gas irOptimized: 93200 +// gas irOptimized: 93017 // gas legacy: 92798 // gas legacyOptimized: 92062 diff --git a/test/libsolidity/semanticTests/array/push/array_push_struct.sol b/test/libsolidity/semanticTests/array/push/array_push_struct.sol index 03a2c53b3f..60e317770f 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_struct.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_struct.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 2, 3, 4, 5 -// gas irOptimized: 137074 +// gas irOptimized: 136894 // gas legacy: 147484 // gas legacyOptimized: 146456 diff --git a/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol b/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol index 272b179e90..f6da6a3985 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test((uint16,uint16,uint16[3],uint16[])): 0x20, 2, 3, 0, 0, 4, 0xC0, 4, 0, 0, 5, 0, 0 -> 2, 3, 4, 5 -// gas irOptimized: 139100 +// gas irOptimized: 138785 // gas legacy: 145150 // gas legacyOptimized: 139171 diff --git a/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol b/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol index 86ef51a810..78c817d446 100644 --- a/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol +++ b/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol @@ -17,6 +17,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0 -// gas irOptimized: 185231 +// gas irOptimized: 176848 // gas legacy: 218028 // gas legacyOptimized: 205124 diff --git a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol index f1a245ce4b..262ba724a5 100644 --- a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol +++ b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> -// gas irOptimized: 179867 +// gas irOptimized: 179590 // gas legacy: 180620 // gas legacyOptimized: 180403 diff --git a/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol b/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol index fe6138a4a1..8df809acd9 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol @@ -29,14 +29,14 @@ contract C { // ---- // l() -> 0 // f(uint256,uint256): 42, 64 -> -// gas irOptimized: 114151 +// gas irOptimized: 112555 // gas legacy: 108234 // gas legacyOptimized: 102245 // l() -> 1 // ll(uint256): 0 -> 43 // a(uint256,uint256): 0, 42 -> 64 // f(uint256,uint256): 84, 128 -> -// gas irOptimized: 119535 +// gas irOptimized: 116427 // gas legacy: 107780 // gas legacyOptimized: 96331 // l() -> 2 diff --git a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol index 093d3aa5a6..defbf41499 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol @@ -23,7 +23,7 @@ contract C { // ---- // l() -> 0 // g(uint256): 70 -> -// gas irOptimized: 191389 +// gas irOptimized: 184507 // gas legacy: 184991 // gas legacyOptimized: 180608 // l() -> 70 diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index 7ae96a3d68..7d2b4d9957 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -26,6 +26,6 @@ contract Main { // compileViaYul: also // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 -// gas irOptimized: 113954 +// gas irOptimized: 113776 // gas legacy: 126852 // gas legacyOptimized: 114079 diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index c55ce061d1..63c2acbb50 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -26,6 +26,6 @@ contract Creator { // compileViaYul: also // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 -// gas irOptimized: 458295 +// gas irOptimized: 456873 // gas legacy: 590939 // gas legacyOptimized: 448582 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index c0123af139..d4d41d80c2 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -26,6 +26,6 @@ contract Creator { // compileViaYul: also // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" -// gas irOptimized: 312176 +// gas irOptimized: 308702 // gas legacy: 429173 // gas legacyOptimized: 298384 diff --git a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol index 3bf97c49ba..3fdbb07854 100644 --- a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol @@ -19,6 +19,6 @@ contract C { // compileViaYul: also // ---- // f(), 2000 ether -> true -// gas irOptimized: 123090 +// gas irOptimized: 123037 // gas legacy: 123226 // gas legacyOptimized: 123092 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol b/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol index 2da24603ef..b5db5ca2b1 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol @@ -15,6 +15,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c -// gas irOptimized: 114816 +// gas irOptimized: 114746 // gas legacy: 116393 // gas legacyOptimized: 114415 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol b/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol index 8e02a5bfc7..f833ba37a7 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol @@ -16,6 +16,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c -// gas irOptimized: 114816 +// gas irOptimized: 114746 // gas legacy: 116393 // gas legacyOptimized: 114415 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol b/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol index f9e773b757..552444dd8b 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol @@ -17,6 +17,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d -// gas irOptimized: 185564 +// gas irOptimized: 185444 // gas legacy: 187621 // gas legacyOptimized: 184551 diff --git a/test/libsolidity/semanticTests/events/event_indexed_mixed.sol b/test/libsolidity/semanticTests/events/event_indexed_mixed.sol index d3971c1e91..47aca1e2ab 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_mixed.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_mixed.sol @@ -13,6 +13,6 @@ contract C { // ---- // deposit() -> // ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, "def" -// gas irOptimized: 23685 +// gas irOptimized: 23709 // gas legacy: 24342 // gas legacyOptimized: 23753 diff --git a/test/libsolidity/semanticTests/events/event_indexed_string.sol b/test/libsolidity/semanticTests/events/event_indexed_string.sol index a411da3c62..d35db93c46 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_string.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_string.sol @@ -19,6 +19,6 @@ contract C { // ---- // deposit() -> // ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81 -// gas irOptimized: 353515 +// gas irOptimized: 343396 // gas legacy: 390742 // gas legacyOptimized: 376774 diff --git a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol index b7be3cf057..9205de434d 100644 --- a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol +++ b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol @@ -76,12 +76,12 @@ contract FixedFeeRegistrar is Registrar { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 433748 +// gas irOptimized: 425623 // gas legacy: 936897 -// gas legacyOptimized: 491019 +// gas legacyOptimized: 490983 // reserve(string), 69 ether: 0x20, 3, "abc" -> // ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 -// gas irOptimized: 46070 +// gas irOptimized: 45967 // gas legacy: 46842 // gas legacyOptimized: 46091 // owner(string): 0x20, 3, "abc" -> 0x1212121212121212121212121212120000000012 diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index 81efd35666..f054497e98 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -178,7 +178,7 @@ contract DepositContract is IDepositContract, ERC165 { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 1657475 +// gas irOptimized: 1558013 // gas legacy: 2580394 // gas legacyOptimized: 1775403 // supportsInterface(bytes4): 0x0 -> 0 @@ -186,27 +186,27 @@ contract DepositContract is IDepositContract, ERC165 { // supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id # // supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e -// gas irOptimized: 122599 +// gas irOptimized: 122169 // gas legacy: 150465 // gas legacyOptimized: 122798 // get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit # // deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e -// gas irOptimized: 122599 +// gas irOptimized: 122169 // gas legacy: 150465 // gas legacyOptimized: 122798 // get_deposit_count() -> 0x20, 8, 0 // deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 # // ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00 // get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438 -// gas irOptimized: 122606 +// gas irOptimized: 122148 // gas legacy: 150475 // gas legacyOptimized: 122811 // get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000 // deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac # // ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000 // get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee -// gas irOptimized: 122606 +// gas irOptimized: 122148 // gas legacy: 150475 // gas legacyOptimized: 122811 // get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol index 77be503012..01d2403a6d 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol @@ -50,46 +50,46 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 1965559 +// gas irOptimized: 1924584 // gas legacy: 2602700 // gas legacyOptimized: 1874490 // div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 -// gas irOptimized: 22244 +// gas irOptimized: 22137 // gas legacy: 22767 // gas legacyOptimized: 22282 // exp(int256): 3141592653589793238 -> 23140692632779268978 -// gas irOptimized: 24358 +// gas irOptimized: 24545 // gas legacy: 25203 // gas legacyOptimized: 24357 // exp2(int256): 3141592653589793238 -> 8824977827076287620 -// gas irOptimized: 24125 +// gas irOptimized: 24257 // gas legacy: 24864 // gas legacyOptimized: 24110 // gm(int256,int256): 3141592653589793238, 88714123 -> 16694419339601 -// gas irOptimized: 23057 +// gas irOptimized: 22970 // gas legacy: 23228 // gas legacyOptimized: 22683 // log10(int256): 3141592653589793238 -> 4971498726941338506 -// gas irOptimized: 30112 +// gas irOptimized: 30609 // gas legacy: 32934 // gas legacyOptimized: 30323 // log2(int256): 3141592653589793238 -> 1651496129472318782 -// gas irOptimized: 28300 +// gas irOptimized: 28819 // gas legacy: 31067 // gas legacyOptimized: 28426 // mul(int256,int256): 3141592653589793238, 88714123 -> 278703637 -// gas irOptimized: 22335 +// gas irOptimized: 22225 // gas legacy: 22807 // gas legacyOptimized: 22295 // pow(int256,uint256): 3141592653589793238, 5 -> 306019684785281453040 -// gas irOptimized: 22861 +// gas irOptimized: 22635 // gas legacy: 23508 // gas legacyOptimized: 22921 // sqrt(int256): 3141592653589793238 -> 1772453850905516027 -// gas irOptimized: 22702 +// gas irOptimized: 22650 // gas legacy: 22802 // gas legacyOptimized: 22422 // benchmark(int256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000 -// gas irOptimized: 37899 +// gas irOptimized: 36630 // gas legacy: 36673 // gas legacyOptimized: 34729 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol index 8a096f5242..c31664c859 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol @@ -50,46 +50,46 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 1769431 +// gas irOptimized: 1778342 // gas legacy: 2356230 // gas legacyOptimized: 1746528 // div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 -// gas irOptimized: 22047 +// gas irOptimized: 22004 // gas legacy: 22497 // gas legacyOptimized: 22010 // exp(uint256): 3141592653589793238 -> 23140692632779268978 -// gas irOptimized: 24234 +// gas irOptimized: 24444 // gas legacy: 25104 // gas legacyOptimized: 24258 // exp2(uint256): 3141592653589793238 -> 8824977827076287620 -// gas irOptimized: 24063 +// gas irOptimized: 24198 // gas legacy: 24814 // gas legacyOptimized: 24062 // gm(uint256,uint256): 3141592653589793238, 88714123 -> 16694419339601 -// gas irOptimized: 23036 +// gas irOptimized: 22950 // gas legacy: 23269 // gas legacyOptimized: 22724 // log10(uint256): 3141592653589793238 -> 0x44fe4fc084a52b8a -// gas irOptimized: 29892 +// gas irOptimized: 30269 // gas legacy: 32898 // gas legacyOptimized: 29925 // log2(uint256): 3141592653589793238 -> 1651496129472318782 -// gas irOptimized: 27822 +// gas irOptimized: 28235 // gas legacy: 30986 // gas legacyOptimized: 28001 // mul(uint256,uint256): 3141592653589793238, 88714123 -> 278703637 -// gas irOptimized: 22094 +// gas irOptimized: 22048 // gas legacy: 22604 // gas legacyOptimized: 22090 // pow(uint256,uint256): 3141592653589793238, 5 -> 306019684785281453040 -// gas irOptimized: 22565 +// gas irOptimized: 22406 // gas legacy: 23245 // gas legacyOptimized: 22646 // sqrt(uint256): 3141592653589793238 -> 1772453850905516027 -// gas irOptimized: 22720 +// gas irOptimized: 22672 // gas legacy: 22820 // gas legacyOptimized: 22440 // benchmark(uint256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000 -// gas irOptimized: 36587 +// gas irOptimized: 35603 // gas legacy: 35385 // gas legacyOptimized: 33449 diff --git a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol index 2c9376b220..1fc85adff7 100644 --- a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol +++ b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol @@ -35,10 +35,10 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 528041 +// gas irOptimized: 465357 // gas legacy: 733634 // gas legacyOptimized: 479606 // prb_pi() -> 3141592656369545286 -// gas irOptimized: 63027 +// gas irOptimized: 57478 // gas legacy: 98903 // gas legacyOptimized: 75735 diff --git a/test/libsolidity/semanticTests/externalContracts/snark.sol b/test/libsolidity/semanticTests/externalContracts/snark.sol index 7a7b956956..8f6b939fdf 100644 --- a/test/libsolidity/semanticTests/externalContracts/snark.sol +++ b/test/libsolidity/semanticTests/externalContracts/snark.sol @@ -297,6 +297,6 @@ contract Test { // pair() -> true // verifyTx() -> true // ~ emit Verified(string): 0x20, 0x16, "Successfully verified." -// gas irOptimized: 101054 +// gas irOptimized: 95261 // gas legacy: 114094 // gas legacyOptimized: 83670 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index 1fa79f382d..238ed21840 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -51,26 +51,26 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 778254 +// gas irOptimized: 702619 // gas legacy: 1188228 // gas legacyOptimized: 750416 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 -// gas irOptimized: 22734 +// gas irOptimized: 22660 // gas legacy: 23190 // gas legacyOptimized: 22508 // roundtrip(string): 0x20, 11, "hello world" -> 0x20, 11, "hello world" -// gas irOptimized: 23513 +// gas irOptimized: 23408 // gas legacy: 23820 // gas legacyOptimized: 23123 // utf8len(string): 0x20, 16, "\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83" -> 4 # Input: "😃😃😃😃" # -// gas irOptimized: 24266 +// gas irOptimized: 24026 // gas legacy: 25716 // gas legacyOptimized: 24115 // multiconcat(string,uint256): 0x40, 3, 11, "hello world" -> 0x20, 0x58, 0x68656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f726c, 0x6468656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f72, 49027192869463622675296414541903001712009715982962058146354235762728281047040 # concatenating 3 times # -// gas irOptimized: 28958 +// gas irOptimized: 28440 // gas legacy: 31621 // gas legacyOptimized: 27914 // benchmark(string,bytes32): 0x40, 0x0842021, 8, "solidity" -> 0x2020 -// gas irOptimized: 2235661 +// gas irOptimized: 2040067 // gas legacy: 4381235 // gas legacyOptimized: 2317529 diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index b4e7efbb58..b50890f559 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -18,7 +18,7 @@ contract C { // compileViaYul: also // ---- // constructor(), 20 wei -// gas irOptimized: 219233 +// gas irOptimized: 220113 // gas legacy: 288299 // gas legacyOptimized: 177933 // f(uint256): 20 -> 1370859564726510389319704988634906228201275401179 @@ -26,7 +26,7 @@ contract C { // f(uint256): 20 -> FAILURE // x() -> 1 // stack(uint256): 1023 -> FAILURE -// gas irOptimized: 349023 +// gas irOptimized: 345821 // gas legacy: 535367 // gas legacyOptimized: 354656 // x() -> 1 diff --git a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol index 5d4f25a39f..f01a590eb3 100644 --- a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol +++ b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol @@ -20,7 +20,7 @@ contract test { // compileViaYul: also // ---- // set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0 -// gas irOptimized: 112020 +// gas irOptimized: 111965 // gas legacy: 113806 // gas legacyOptimized: 111781 // get(uint8): 1 -> 21, 22, 42, 43 diff --git a/test/libsolidity/semanticTests/functionTypes/store_function.sol b/test/libsolidity/semanticTests/functionTypes/store_function.sol index ddebc11b7c..c2678a91de 100644 --- a/test/libsolidity/semanticTests/functionTypes/store_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/store_function.sol @@ -28,6 +28,6 @@ contract C { // compileViaYul: also // ---- // t() -> 9 -// gas irOptimized: 99010 +// gas irOptimized: 99186 // gas legacy: 159083 // gas legacyOptimized: 108916 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index a183069846..cd5992ce6e 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -29,7 +29,7 @@ contract C { // compileViaYul: also // ---- // f() -> 3, 7, 5 -// gas irOptimized: 127613 +// gas irOptimized: 127592 // gas legacy: 151590 // gas legacyOptimized: 125422 // x() -> 7 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index 651ac994ee..0dc9845f4d 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -23,8 +23,8 @@ contract D { // compileViaYul: also // ---- // f() -> 1 -// gas irOptimized: 78722 +// gas irOptimized: 77164 // gas legacy: 115012 // g() -> 5 -// gas irOptimized: 78811 +// gas irOptimized: 77231 // gas legacy: 115558 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol index 85b1fca3bb..e012accafe 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol @@ -25,5 +25,5 @@ contract B { // compileViaYul: also // ---- // g() -> 42 -// gas irOptimized: 84629 +// gas irOptimized: 80945 // gas legacy: 125609 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol index b4f03446ce..4105577f05 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -25,6 +25,6 @@ contract B { // compileViaYul: also // ---- // g() -> 42 -// gas irOptimized: 105784 +// gas irOptimized: 111913 // gas legacy: 185181 // gas legacyOptimized: 114726 diff --git a/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol b/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol index 88ead1eb3d..85a93b3dc8 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol @@ -26,10 +26,10 @@ contract C { // compileViaYul: also // ---- // f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80 -// gas irOptimized: 22306 +// gas irOptimized: 22239 // gas legacy: 23385 // gas legacyOptimized: 23092 // g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80 -// gas irOptimized: 21287 +// gas irOptimized: 21277 // gas legacy: 21462 // gas legacyOptimized: 21256 diff --git a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol index 70f52d4c6c..11cb938320 100644 --- a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol +++ b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol @@ -37,10 +37,10 @@ contract C { // compileViaYul: also // ---- // convertParent() -> 1 -// gas irOptimized: 87655 +// gas irOptimized: 85640 // convertSubA() -> 1, 2 -// gas irOptimized: 88451 +// gas irOptimized: 86395 // gas legacy: 99303 // convertSubB() -> 1, 3 -// gas irOptimized: 88385 +// gas irOptimized: 86338 // gas legacy: 99237 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create.sol b/test/libsolidity/semanticTests/salted_create/salted_create.sol index 064159de37..5374d23521 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create.sol @@ -22,6 +22,6 @@ contract A { // ---- // different_salt() -> true // same_salt() -> true -// gas irOptimized: 98438948 +// gas irOptimized: 98438914 // gas legacy: 98439116 // gas legacyOptimized: 98438970 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol index 2e386ee454..17edaf3eb4 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -22,6 +22,6 @@ contract A { // compileViaYul: also // ---- // f(), 10 ether -> 3007, 3008, 3009 -// gas irOptimized: 270255 +// gas irOptimized: 273275 // gas legacy: 422885 // gas legacyOptimized: 287856 diff --git a/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol b/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol index 2fdff6c561..caa3858877 100644 --- a/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol +++ b/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol @@ -46,6 +46,6 @@ contract C { // compileViaYul: also // ---- // test() -> true -// gas irOptimized: 135141 +// gas irOptimized: 134587 // gas legacy: 136036 // gas legacyOptimized: 133480 diff --git a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol index 3587d8e17c..7b84033d87 100644 --- a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol +++ b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol @@ -18,6 +18,6 @@ contract C { // compileViaYul: also // ---- // f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88 -// gas irOptimized: 203716 +// gas irOptimized: 203397 // gas legacy: 209194 // gas legacyOptimized: 203583 diff --git a/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol b/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol index 93b63ff5c1..0d0aba8c8f 100644 --- a/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol +++ b/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol @@ -25,6 +25,6 @@ contract CopyTest { // compileViaYul: also // ---- // run() -> 2, 23, 42 -// gas irOptimized: 195077 +// gas irOptimized: 193980 // gas legacy: 186016 // gas legacyOptimized: 184668 diff --git a/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol b/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol index f48c548078..12ec4ca181 100644 --- a/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol +++ b/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol @@ -69,7 +69,7 @@ contract Test { // compileViaYul: also // ---- // load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 -// gas irOptimized: 111174 +// gas irOptimized: 111179 // gas legacy: 112999 // gas legacyOptimized: 110881 // store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 diff --git a/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol b/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol index 070fcf920d..a677b5be8d 100644 --- a/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol +++ b/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol @@ -25,7 +25,7 @@ contract c { // ---- // storageEmpty -> 1 // set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true -// gas irOptimized: 133819 +// gas irOptimized: 133752 // gas legacy: 134436 // gas legacyOptimized: 133879 // test(uint256): 32 -> "3" diff --git a/test/libsolidity/semanticTests/structs/struct_copy.sol b/test/libsolidity/semanticTests/structs/struct_copy.sol index ccaaeaa52d..0bbb6489e9 100644 --- a/test/libsolidity/semanticTests/structs/struct_copy.sol +++ b/test/libsolidity/semanticTests/structs/struct_copy.sol @@ -38,12 +38,12 @@ contract c { // compileViaYul: also // ---- // set(uint256): 7 -> true -// gas irOptimized: 109985 +// gas irOptimized: 110011 // gas legacy: 110616 // gas legacyOptimized: 110006 // retrieve(uint256): 7 -> 1, 3, 4, 2 // copy(uint256,uint256): 7, 8 -> true -// gas irOptimized: 118701 +// gas irOptimized: 118707 // gas legacy: 119166 // gas legacyOptimized: 118622 // retrieve(uint256): 7 -> 1, 3, 4, 2 diff --git a/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol b/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol index 441584a5e3..21757ea407 100644 --- a/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol +++ b/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol @@ -21,6 +21,6 @@ contract c { // compileViaYul: also // ---- // test() -> true -// gas irOptimized: 110144 +// gas irOptimized: 110186 // gas legacy: 110627 // gas legacyOptimized: 109706 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol index 8385396287..bc18d31922 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol @@ -33,4 +33,4 @@ contract C { // compileViaYul: true // ---- // f() -> 0, 0, 0 -// gas irOptimized: 117388 +// gas irOptimized: 117289 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol index 14e170a4c6..e759520b47 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol @@ -44,7 +44,7 @@ contract C { // compileViaYul: also // ---- // f() -> -// gas irOptimized: 121704 +// gas irOptimized: 121618 // gas legacy: 122132 // gas legacyOptimized: 121500 // g() -> diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol index 6425c0d373..6f88df3949 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol @@ -27,4 +27,4 @@ contract C { // compileViaYul: true // ---- // f() -> 0 -// gas irOptimized: 112160 +// gas irOptimized: 111896 diff --git a/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol b/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol index caa2b693fe..fe791a68dd 100644 --- a/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol +++ b/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol @@ -32,6 +32,6 @@ contract C { // compileViaYul: also // ---- // f() -> 42, 23, 34, 42, 42 -// gas irOptimized: 110592 +// gas irOptimized: 110966 // gas legacy: 112021 // gas legacyOptimized: 110548 diff --git a/test/libsolidity/semanticTests/structs/structs.sol b/test/libsolidity/semanticTests/structs/structs.sol index 46b596e398..b56a2ec229 100644 --- a/test/libsolidity/semanticTests/structs/structs.sol +++ b/test/libsolidity/semanticTests/structs/structs.sol @@ -32,7 +32,7 @@ contract test { // ---- // check() -> false // set() -> -// gas irOptimized: 134389 +// gas irOptimized: 134335 // gas legacy: 135277 // gas legacyOptimized: 134064 // check() -> true diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol index 3596d2c992..1927b25192 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol @@ -51,11 +51,11 @@ contract C { // compileViaYul: also // ---- // test_f() -> true -// gas irOptimized: 122887 +// gas irOptimized: 122509 // gas legacy: 126168 // gas legacyOptimized: 123199 // test_g() -> true -// gas irOptimized: 96673 +// gas irOptimized: 95980 // gas legacy: 101311 // gas legacyOptimized: 96566 // addresses(uint256): 0 -> 0x18 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol index 9827d6cd13..433d1969c6 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol @@ -25,18 +25,18 @@ contract C { // ---- // s() -> 0, 0, 0x00, 0 // f((uint8,uint16,bytes2,uint8)): 1, 0xff, "ab", 15 -> -// gas irOptimized: 44860 +// gas irOptimized: 44786 // gas legacy: 47200 // gas legacyOptimized: 44923 // s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15 // g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3 -// gas irOptimized: 69306 +// gas irOptimized: 69097 // gas legacy: 75466 // gas legacyOptimized: 74255 // small(uint256): 0 -> 1 // small(uint256): 1 -> 2 // h(bytes2[]): 0x20, 3, "ab", "cd", "ef" -> 0x20, 3, "ab", "cd", "ef" -// gas irOptimized: 69510 +// gas irOptimized: 69174 // gas legacy: 75156 // gas legacyOptimized: 74342 // l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol index 155a4bd87f..4db14ff739 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol @@ -115,33 +115,33 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 462361 +// gas irOptimized: 442239 // gas legacy: 861547 // gas legacyOptimized: 420959 // totalSupply() -> 20 -// gas irOptimized: 23378 +// gas irOptimized: 23415 // gas legacy: 23653 // gas legacyOptimized: 23368 // transfer(address,uint256): 2, 5 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05 -// gas irOptimized: 48503 +// gas irOptimized: 48471 // gas legacy: 49572 // gas legacyOptimized: 48575 // decreaseAllowance(address,uint256): 2, 0 -> true // ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00 -// gas irOptimized: 26327 +// gas irOptimized: 26275 // gas legacy: 27204 // gas legacyOptimized: 26317 // decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24040 +// gas irOptimized: 24042 // gas legacy: 24506 // gas legacyOptimized: 24077 // transfer(address,uint256): 2, 14 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e -// gas irOptimized: 28603 +// gas irOptimized: 28571 // gas legacy: 29672 // gas legacyOptimized: 28675 // transfer(address,uint256): 2, 2 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24052 +// gas irOptimized: 24071 // gas legacy: 24492 // gas legacyOptimized: 24074 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol b/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol index e1a7c1c5b1..04e9936823 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol @@ -25,18 +25,18 @@ contract C { // ---- // s() -> 0, 0, 0x00, 0 // f((uint8,uint16,bytes2,uint8)): 1, 0xff, "ab", 15 -> -// gas irOptimized: 44551 +// gas irOptimized: 44536 // gas legacy: 46213 // gas legacyOptimized: 44671 // s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15 // g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3 -// gas irOptimized: 69671 +// gas irOptimized: 69555 // gas legacy: 76557 // gas legacyOptimized: 74834 // small(uint256): 0 -> 1 // small(uint256): 1 -> 2 // h(bytes2[]): 0x20, 3, "ab", "cd", "ef" -> 0x20, 3, "ab", "cd", "ef" -// gas irOptimized: 69928 +// gas irOptimized: 69617 // gas legacy: 76238 // gas legacyOptimized: 74921 // l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol index d7b9db30b1..d2d46c7088 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol @@ -20,18 +20,18 @@ contract C { // compileViaYul: also // ---- // getX() -> 0 -// gas irOptimized: 23353 +// gas irOptimized: 23379 // gas legacy: 23479 // gas legacyOptimized: 23311 // setX(int256): 5 -> -// gas irOptimized: 43511 +// gas irOptimized: 43510 // gas legacy: 43724 // gas legacyOptimized: 43516 // getX() -> 5 -// gas irOptimized: 23353 +// gas irOptimized: 23379 // gas legacy: 23479 // gas legacyOptimized: 23311 // add(int256,int256): 200, 99 -> 299 -// gas irOptimized: 21794 +// gas irOptimized: 21764 // gas legacy: 22394 // gas legacyOptimized: 21813 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol index 29038a8617..44d87c397c 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol @@ -21,18 +21,18 @@ contract C { // compileViaYul: also // ---- // getX() -> 0 -// gas irOptimized: 23353 +// gas irOptimized: 23379 // gas legacy: 23608 // gas legacyOptimized: 23311 // setX(int256): 5 -> -// gas irOptimized: 43511 +// gas irOptimized: 43510 // gas legacy: 43724 // gas legacyOptimized: 43516 // getX() -> 5 -// gas irOptimized: 23353 +// gas irOptimized: 23379 // gas legacy: 23608 // gas legacyOptimized: 23311 // add(int256,int256): 200, 99 -> 299 -// gas irOptimized: 21794 +// gas irOptimized: 21764 // gas legacy: 22523 // gas legacyOptimized: 21813 diff --git a/test/libsolidity/semanticTests/various/destructuring_assignment.sol b/test/libsolidity/semanticTests/various/destructuring_assignment.sol index b8a314d32c..ee6f7690db 100644 --- a/test/libsolidity/semanticTests/various/destructuring_assignment.sol +++ b/test/libsolidity/semanticTests/various/destructuring_assignment.sol @@ -36,6 +36,6 @@ contract C { // compileViaYul: also // ---- // f(bytes): 0x20, 0x5, "abcde" -> 0 -// gas irOptimized: 240334 +// gas irOptimized: 240685 // gas legacy: 240358 // gas legacyOptimized: 239682 diff --git a/test/libsolidity/semanticTests/various/erc20.sol b/test/libsolidity/semanticTests/various/erc20.sol index 6e7487ee57..204e620d62 100644 --- a/test/libsolidity/semanticTests/various/erc20.sol +++ b/test/libsolidity/semanticTests/various/erc20.sol @@ -98,33 +98,33 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 459547 +// gas irOptimized: 437697 // gas legacy: 833310 // gas legacyOptimized: 416135 // totalSupply() -> 20 -// gas irOptimized: 23378 +// gas irOptimized: 23415 // gas legacy: 23524 // gas legacyOptimized: 23368 // transfer(address,uint256): 2, 5 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05 -// gas irOptimized: 48503 +// gas irOptimized: 48471 // gas legacy: 49317 // gas legacyOptimized: 48491 // decreaseAllowance(address,uint256): 2, 0 -> true // ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00 -// gas irOptimized: 26327 +// gas irOptimized: 26275 // gas legacy: 27012 // gas legacyOptimized: 26275 // decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24040 +// gas irOptimized: 24042 // gas legacy: 24467 // gas legacyOptimized: 24056 // transfer(address,uint256): 2, 14 -> true // ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e -// gas irOptimized: 28603 +// gas irOptimized: 28571 // gas legacy: 29417 // gas legacyOptimized: 28591 // transfer(address,uint256): 2, 2 -> FAILURE, hex"4e487b71", 0x11 -// gas irOptimized: 24052 +// gas irOptimized: 24071 // gas legacy: 24453 // gas legacyOptimized: 24053 diff --git a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol index a8e9ce1ed8..8ef472136a 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -22,6 +22,6 @@ contract C { // compileViaYul: also // ---- // g() -> 2, 6 -// gas irOptimized: 178952 +// gas irOptimized: 178953 // gas legacy: 180890 // gas legacyOptimized: 179609 diff --git a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol index 33afcb66f8..ab6d6e59a0 100644 --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol @@ -38,10 +38,10 @@ contract D { // f() -> 0x1 # This should work, next should throw # // gas legacy: 103844 // fview() -> FAILURE -// gas irOptimized: 98438630 +// gas irOptimized: 98438627 // gas legacy: 98438803 // gas legacyOptimized: 98438596 // fpure() -> FAILURE -// gas irOptimized: 98438630 +// gas irOptimized: 98438627 // gas legacy: 98438803 // gas legacyOptimized: 98438597 diff --git a/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol b/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol index 12e491968b..c8398b2bf3 100644 --- a/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol +++ b/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol @@ -30,7 +30,7 @@ contract c { // x() -> 0, 0 // y() -> 0, 0 // set() -> -// gas irOptimized: 109734 +// gas irOptimized: 109733 // gas legacy: 109732 // gas legacyOptimized: 109682 // x() -> 1, 2 diff --git a/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol b/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol index 83aefbc61c..b603fb7864 100644 --- a/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol +++ b/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol @@ -28,7 +28,7 @@ contract C { // index(uint256): 10 -> true // index(uint256): 20 -> true // index(uint256): 0xFF -> true -// gas irOptimized: 151952 +// gas irOptimized: 138441 // gas legacy: 248854 // gas legacyOptimized: 152638 // accessIndex(uint256,int256): 10, 1 -> 2 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol b/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol index 5241f29c07..24d0e9f145 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol @@ -18,33 +18,33 @@ contract C { // ---- // test_indices(uint256): 1 -> // test_indices(uint256): 129 -> -// gas irOptimized: 3041780 +// gas irOptimized: 3032986 // gas legacy: 3071205 // gas legacyOptimized: 3011873 // test_indices(uint256): 5 -> -// gas irOptimized: 368208 +// gas irOptimized: 367642 // gas legacy: 369241 // gas legacyOptimized: 366149 // test_indices(uint256): 10 -> // test_indices(uint256): 15 -> -// gas irOptimized: 73803 +// gas irOptimized: 72860 // test_indices(uint256): 0xFF -> -// gas irOptimized: 3455818 +// gas irOptimized: 3438610 // gas legacy: 3514167 // gas legacyOptimized: 3398107 // test_indices(uint256): 1000 -> -// gas irOptimized: 18383600 +// gas irOptimized: 18318372 // gas legacy: 18617999 // gas legacyOptimized: 18178944 // test_indices(uint256): 129 -> -// gas irOptimized: 2742698 +// gas irOptimized: 2733570 // gas legacy: 2772735 // gas legacyOptimized: 2716547 // test_indices(uint256): 128 -> -// gas irOptimized: 434013 +// gas irOptimized: 426682 // gas legacy: 467272 // gas legacyOptimized: 418424 // test_indices(uint256): 1 -> -// gas irOptimized: 363418 +// gas irOptimized: 363074 // gas legacy: 363407 // gas legacyOptimized: 361811 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol b/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol index 4b377ec2da..975130c517 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol @@ -18,11 +18,11 @@ contract C { // test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex"4e487b71", 0x32 // test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex"4e487b71", 0x32 // test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex"4e487b71", 0x32 -// gas irOptimized: 139319 +// gas irOptimized: 137849 // gas legacy: 131830 // gas legacyOptimized: 112054 // test_boundary_check(uint256,uint256): 256, 255 -> 0 -// gas irOptimized: 141481 +// gas irOptimized: 140028 // gas legacy: 134149 // gas legacyOptimized: 114233 // test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex"4e487b71", 0x32 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol b/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol index 870f339fc0..b2e0cb5467 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol @@ -54,18 +54,18 @@ contract C { // ---- // test_zeroed_indicies(uint256): 1 -> // test_zeroed_indicies(uint256): 5 -> -// gas irOptimized: 131736 +// gas irOptimized: 131197 // gas legacy: 132367 // gas legacyOptimized: 129586 // test_zeroed_indicies(uint256): 10 -> -// gas irOptimized: 175795 +// gas irOptimized: 174805 // gas legacy: 177329 // gas legacyOptimized: 172224 // test_zeroed_indicies(uint256): 15 -> -// gas irOptimized: 199485 +// gas irOptimized: 198055 // gas legacy: 201954 // gas legacyOptimized: 194604 // test_zeroed_indicies(uint256): 0xFF -> -// gas irOptimized: 6123320 +// gas irOptimized: 6098185 // gas legacy: 6163149 // gas legacyOptimized: 6029474 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol b/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol index 47b75c08ea..c5af584495 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol @@ -14,11 +14,11 @@ contract C { // set_get_length(uint256): 10 -> 10 // set_get_length(uint256): 20 -> 20 // set_get_length(uint256): 0xFF -> 0xFF -// gas irOptimized: 96934 +// gas irOptimized: 96690 // gas legacy: 126722 // gas legacyOptimized: 107818 // set_get_length(uint256): 0xFFF -> 0xFFF -// gas irOptimized: 1221706 +// gas irOptimized: 1217857 // gas legacy: 1702119 // gas legacyOptimized: 1398420 // set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas # diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol index 05970805f9..5c7c4cba84 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol @@ -13,11 +13,11 @@ contract C { // compileViaYul: also // ---- // pushEmpty(uint256): 128 -// gas irOptimized: 414881 +// gas irOptimized: 412570 // gas legacy: 417287 // gas legacyOptimized: 399048 // pushEmpty(uint256): 256 -// gas irOptimized: 706405 +// gas irOptimized: 702558 // gas legacy: 715083 // gas legacyOptimized: 688908 // pushEmpty(uint256): 38869 -> FAILURE # out-of-gas # diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol index 06e00f6db9..5e5d1c962c 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol @@ -18,15 +18,15 @@ contract C { // set_get_length(uint256): 10 -> 10 // set_get_length(uint256): 20 -> 20 // set_get_length(uint256): 0 -> 0 -// gas irOptimized: 77961 +// gas irOptimized: 77628 // gas legacy: 77730 // gas legacyOptimized: 77162 // set_get_length(uint256): 0xFF -> 0xFF -// gas irOptimized: 143348 +// gas irOptimized: 141805 // gas legacy: 678237 // gas legacyOptimized: 115104 // set_get_length(uint256): 0xFFF -> 0xFFF -// gas irOptimized: 1824725 +// gas irOptimized: 1801672 // gas legacy: 9873774 // gas legacyOptimized: 1398546 // set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas # diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol b/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol index 7cc1f9e544..e802e3687b 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol @@ -15,15 +15,15 @@ contract C { // set_get_length(uint256): 1 -> 0 // set_get_length(uint256): 10 -> 0 // set_get_length(uint256): 20 -> 0 -// gas irOptimized: 86888 +// gas irOptimized: 86331 // gas legacy: 85822 // gas legacyOptimized: 83608 // set_get_length(uint256): 0xFF -> 0 -// gas irOptimized: 828783 +// gas irOptimized: 821881 // gas legacy: 810327 // gas legacyOptimized: 786258 // set_get_length(uint256): 0xFFF -> 0 -// gas irOptimized: 12951675 +// gas irOptimized: 12841093 // gas legacy: 12649059 // gas legacyOptimized: 12267870 // set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas # diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 38ef5ad39d..8986acc1b0 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -20,6 +20,10 @@ #include #include +#include +#include + +#include #include @@ -61,7 +65,18 @@ TestCase::TestResult EVMCodeTransformTest::run(ostream& _stream, string const& _ return TestResult::FatalError; } - m_obtainedResult = evmasm::disassemble(stack.assemble(AssemblyStack::Machine::EVM).bytecode->bytecode, "\n"); + evmasm::Assembly assembly; + EthAssemblyAdapter adapter(assembly); + EVMObjectCompiler::compile( + *stack.parserResult(), + adapter, + EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}), + m_stackOpt + ); + + std::ostringstream output; + output << assembly; + m_obtainedResult = output.str(); return checkResult(_stream, _linePrefix, _formatted); } diff --git a/test/libyul/evmCodeTransform/early_push_on_deep_swap.yul b/test/libyul/evmCodeTransform/early_push_on_deep_swap.yul new file mode 100644 index 0000000000..5e119cc73f --- /dev/null +++ b/test/libyul/evmCodeTransform/early_push_on_deep_swap.yul @@ -0,0 +1,54 @@ +{ + extcodecopy(div(div(call(call(gas(),0x10000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000, 0x1000000000000000000000000000000000000000000000000000, 0x10000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000, 0x1000000000000000000000000000000000000000000000000000000), 0x10000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x1000000000000000000000000000000000000000000000000000000000, 0x10000000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000000, 0x1000000000000000000000000000000000000000000000000000000000000),0x10000000000000000000000000000000000000000000000000000000000000),0x100000000000000000000000000000000000000000000000000000000000000), 0x1000000000000000000000000000000000000000000000000000000000000000, 0x1000000000000000000000000000000000000000000000000000000000000001, 0x100000000000000000000000000000000000000000000000000000000000001) +} +// ==== +// stackOptimization: true +// ---- +// /* "":1027:1092 */ +// 0x0100000000000000000000000000000000000000000000000000000000000001 +// /* "":959:1025 */ +// 0x1000000000000000000000000000000000000000000000000000000000000001 +// /* "":891:957 */ +// 0x1000000000000000000000000000000000000000000000000000000000000000 +// /* "":823:888 */ +// 0x0100000000000000000000000000000000000000000000000000000000000000 +// /* "":757:821 */ +// 0x10000000000000000000000000000000000000000000000000000000000000 +// /* "":692:755 */ +// 0x01000000000000000000000000000000000000000000000000000000000000 +// /* "":628:690 */ +// 0x100000000000000000000000000000000000000000000000000000000000 +// /* "":565:626 */ +// 0x010000000000000000000000000000000000000000000000000000000000 +// /* "":503:563 */ +// 0x1000000000000000000000000000000000000000000000000000000000 +// /* "":442:501 */ +// 0x0100000000000000000000000000000000000000000000000000000000 +// /* "":382:440 */ +// 0x10000000000000000000000000000000000000000000000000000000 +// /* "":322:379 */ +// 0x01000000000000000000000000000000000000000000000000000000 +// /* "":264:320 */ +// 0x100000000000000000000000000000000000000000000000000000 +// /* "":207:262 */ +// 0x010000000000000000000000000000000000000000000000000000 +// /* "":151:205 */ +// 0x1000000000000000000000000000000000000000000000000000 +// /* "":96:149 */ +// 0x0100000000000000000000000000000000000000000000000000 +// /* "":42:94 */ +// 0x10000000000000000000000000000000000000000000000000 +// /* "":36:41 */ +// gas +// /* "":31:380 */ +// call +// /* "":26:756 */ +// call +// /* "":22:822 */ +// div +// /* "":18:889 */ +// div +// /* "":6:1093 */ +// extcodecopy +// /* "":0:1095 */ +// stop diff --git a/test/libyul/evmCodeTransform/literal_loop.yul b/test/libyul/evmCodeTransform/literal_loop.yul new file mode 100644 index 0000000000..d743836cbc --- /dev/null +++ b/test/libyul/evmCodeTransform/literal_loop.yul @@ -0,0 +1,74 @@ +object "main" { + code { + codecopy(0, dataoffset("deployed"), datasize("deployed")) + return(0, datasize("deployed")) + } + object "deployed" { + code { + for {} + add(delegatecall(delegatecall(call(selfbalance(), 0x0, 0x0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0x0, 0x0, 0x0),0x0) + {} + {} + } + } +} +// ==== +// stackOptimization: true +// ---- +// /* "":62:82 */ +// dataSize(sub_0) +// /* "":38:60 */ +// dataOffset(sub_0) +// /* "":35:36 */ +// 0x00 +// /* "":26:83 */ +// codecopy +// /* "":96:116 */ +// dataSize(sub_0) +// /* "":93:94 */ +// 0x00 +// /* "":86:117 */ +// return +// stop +// +// sub_0: assembly { +// /* "":164:300 */ +// tag_1: +// /* "":296:299 */ +// 0x00 +// /* "":199:212 */ +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// dup1 +// selfbalance +// /* "":194:243 */ +// call +// /* "":181:269 */ +// delegatecall +// /* "":168:295 */ +// delegatecall +// /* "":164:300 */ +// add +// tag_2 +// jumpi +// /* "":154:312 */ +// tag_3: +// stop +// /* "":310:312 */ +// tag_2: +// /* "":304:306 */ +// jump(tag_1) +// } diff --git a/test/libyul/evmCodeTransform/nonempty_initial_layout.yul b/test/libyul/evmCodeTransform/nonempty_initial_layout.yul new file mode 100644 index 0000000000..eb1a787c06 --- /dev/null +++ b/test/libyul/evmCodeTransform/nonempty_initial_layout.yul @@ -0,0 +1,17 @@ +{ + if 0x2000000000000000000000000000000000000000000000000000000000 {} +} +// ==== +// stackOptimization: true +// ---- +// /* "":9:69 */ +// 0x2000000000000000000000000000000000000000000000000000000000 +// /* "":6:72 */ +// tag_1 +// jumpi +// /* "":0:74 */ +// tag_2: +// stop +// /* "":70:72 */ +// tag_1: +// jump(tag_2) diff --git a/test/libyul/evmCodeTransform/stackReuse/for_1.yul b/test/libyul/evmCodeTransform/stackReuse/for_1.yul index e2f4ba128e..b02710598f 100644 --- a/test/libyul/evmCodeTransform/stackReuse/for_1.yul +++ b/test/libyul/evmCodeTransform/stackReuse/for_1.yul @@ -2,18 +2,15 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// POP -// JUMPDEST -// PUSH1 0x1 -// ISZERO -// PUSH1 0x11 -// JUMPI -// PUSH1 0x3 -// POP -// JUMPDEST -// PUSH1 0x3 -// JUMP -// JUMPDEST -// PUSH1 0x2 -// POP +// /* "":17:18 */ +// 0x00 +// /* "":6:20 */ +// pop +// /* "":27:41 */ +// tag_1: +// /* "":38:39 */ +// 0x03 +// /* "":27:41 */ +// pop +// /* "":23:26 */ +// jump(tag_1) diff --git a/test/libyul/evmCodeTransform/stackReuse/for_2.yul b/test/libyul/evmCodeTransform/stackReuse/for_2.yul index f1f7460d48..37d372fb99 100644 --- a/test/libyul/evmCodeTransform/stackReuse/for_2.yul +++ b/test/libyul/evmCodeTransform/stackReuse/for_2.yul @@ -2,21 +2,19 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// JUMPDEST -// PUSH1 0x1 -// ISZERO -// PUSH1 0x14 -// JUMPI -// PUSH1 0x8 -// SWAP1 -// POP -// PUSH1 0x3 -// POP -// JUMPDEST -// PUSH1 0x2 -// JUMP -// JUMPDEST -// POP -// PUSH1 0x2 -// POP +// /* "":17:18 */ +// 0x00 +// /* "":6:20 */ +// pop +// /* "":27:48 */ +// tag_1: +// /* "":34:35 */ +// 0x08 +// /* "":36:46 */ +// pop +// /* "":45:46 */ +// 0x03 +// /* "":27:48 */ +// pop +// /* "":23:26 */ +// jump(tag_1) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul index 13048c020a..96637da89f 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul @@ -4,25 +4,23 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x17 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// DUP3 -// DUP2 -// SSTORE -// POP -// CALLVALUE -// POP -// PUSH1 0x0 -// DUP2 -// SWAP1 -// POP -// JUMPDEST -// SWAP3 -// SWAP2 -// POP -// POP -// JUMP -// JUMPDEST +// /* "":0:88 */ +// stop +// /* "":6:86 */ +// tag_1: +// swap2 +// swap1 +// swap2 +// /* "":37:46 */ +// address +// /* "":33:47 */ +// pop +// /* "":48:60 */ +// sstore +// /* "":65:76 */ +// callvalue +// /* "":61:77 */ +// pop +// /* "":6:86 */ +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul index d1f6b5bdc8..385c253df5 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse_without_retparams.yul @@ -7,23 +7,31 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x17 -// JUMP -// JUMPDEST -// DUP1 -// PUSH1 0x80 -// MSTORE -// POP -// PUSH1 0x0 -// CALLDATALOAD -// ISZERO -// PUSH1 0x13 -// JUMPI -// DUP1 -// DUP2 -// SSTORE -// JUMPDEST -// POP -// JUMPDEST -// JUMP -// JUMPDEST +// /* "":0:88 */ +// stop +// /* "":4:86 */ +// tag_1: +// /* "":34:38 */ +// 0x80 +// /* "":27:42 */ +// mstore +// /* "":63:64 */ +// 0x00 +// /* "":50:65 */ +// calldataload +// /* "":47:82 */ +// tag_2 +// jumpi +// /* "":21:86 */ +// tag_3: +// /* "":4:86 */ +// pop +// jump // out +// /* "":66:82 */ +// tag_2: +// /* "":68:80 */ +// dup1 +// sstore +// /* "":66:82 */ +// codesize +// jump(tag_3) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_call.yul b/test/libyul/evmCodeTransform/stackReuse/function_call.yul index c14ccff365..1abc8d8aff 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_call.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_call.yul @@ -6,28 +6,35 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x9 -// PUSH1 0x2 -// PUSH1 0x1 -// PUSH1 0xD -// JUMP -// JUMPDEST -// PUSH1 0x15 -// JUMP -// JUMPDEST -// POP -// POP -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST -// PUSH1 0x1F -// PUSH1 0x4 -// PUSH1 0x3 -// PUSH1 0xD -// JUMP -// JUMPDEST -// SWAP1 -// POP -// POP +// /* "":15:22 */ +// tag_1 +// /* "":20:21 */ +// 0x02 +// /* "":17:18 */ +// 0x01 +// /* "":15:22 */ +// tag_2 +// jump // in +// tag_1: +// /* "":62:69 */ +// pop +// tag_3 +// /* "":67:68 */ +// 0x04 +// /* "":64:65 */ +// 0x03 +// /* "":62:69 */ +// tag_2 +// jump // in +// tag_3: +// /* "":0:71 */ +// stop +// /* "":27:52 */ +// tag_2: +// pop +// pop +// /* "":47:48 */ +// 0x00 +// /* "":27:52 */ +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul b/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul index aa4567a906..17ccdd3caf 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul @@ -25,92 +25,86 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x80 -// JUMP -// JUMPDEST -// DUP1 -// PUSH2 0x100 -// MSTORE -// POP -// DUP1 -// PUSH2 0x120 -// MSTORE -// POP -// DUP1 -// PUSH2 0x140 -// MSTORE -// POP -// DUP1 -// PUSH2 0x160 -// MSTORE -// POP -// DUP1 -// PUSH2 0x180 -// MSTORE -// POP -// DUP1 -// PUSH2 0x1A0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x1C0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x1E0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x200 -// MSTORE -// POP -// DUP1 -// PUSH2 0x220 -// MSTORE -// POP -// DUP1 -// PUSH2 0x240 -// MSTORE -// POP -// DUP1 -// PUSH2 0x260 -// MSTORE -// POP -// DUP1 -// PUSH2 0x280 -// MSTORE -// POP -// DUP1 -// PUSH2 0x2A0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x2C0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x2E0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x300 -// MSTORE -// POP -// DUP1 -// PUSH2 0x320 -// MSTORE -// POP -// DUP1 -// PUSH2 0x340 -// MSTORE -// POP -// PUSH1 0x0 -// DUP2 -// SWAP1 -// POP -// JUMPDEST -// SWAP2 -// SWAP1 -// POP -// JUMP -// JUMPDEST +// /* "":0:662 */ +// stop +// /* "":6:660 */ +// tag_1: +// /* "":130:136 */ +// 0x0100 +// /* "":123:141 */ +// mstore +// /* "":157:163 */ +// 0x0120 +// /* "":150:168 */ +// mstore +// /* "":184:190 */ +// 0x0140 +// /* "":177:195 */ +// mstore +// /* "":211:217 */ +// 0x0160 +// /* "":204:222 */ +// mstore +// /* "":238:244 */ +// 0x0180 +// /* "":231:249 */ +// mstore +// /* "":265:271 */ +// 0x01a0 +// /* "":258:276 */ +// mstore +// /* "":292:298 */ +// 0x01c0 +// /* "":285:303 */ +// mstore +// /* "":319:325 */ +// 0x01e0 +// /* "":312:330 */ +// mstore +// /* "":346:352 */ +// 0x0200 +// /* "":339:357 */ +// mstore +// /* "":373:379 */ +// 0x0220 +// /* "":366:385 */ +// mstore +// /* "":401:407 */ +// 0x0240 +// /* "":394:413 */ +// mstore +// /* "":429:435 */ +// 0x0260 +// /* "":422:441 */ +// mstore +// /* "":457:463 */ +// 0x0280 +// /* "":450:469 */ +// mstore +// /* "":485:491 */ +// 0x02a0 +// /* "":478:497 */ +// mstore +// /* "":513:519 */ +// 0x02c0 +// /* "":506:525 */ +// mstore +// /* "":541:547 */ +// 0x02e0 +// /* "":534:553 */ +// mstore +// /* "":569:575 */ +// 0x0300 +// /* "":562:581 */ +// mstore +// /* "":597:603 */ +// 0x0320 +// /* "":590:609 */ +// mstore +// /* "":625:631 */ +// 0x0340 +// /* "":618:637 */ +// mstore +// /* "":6:660 */ +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params.yul b/test/libyul/evmCodeTransform/stackReuse/function_params.yul index 60139bb769..e8d9bb30cc 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params.yul @@ -4,11 +4,10 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x8 -// JUMP -// JUMPDEST -// POP -// POP -// JUMPDEST -// JUMP -// JUMPDEST +// /* "":0:28 */ +// stop +// /* "":6:26 */ +// tag_1: +// pop +// pop +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul index 3228637dc5..5292034005 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul @@ -8,17 +8,18 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x10 -// JUMP -// JUMPDEST -// POP -// POP -// POP -// POP -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST +// /* "":212:254 */ +// stop +// /* "":218:252 */ +// tag_1: +// pop +// pop +// pop +// pop +// /* "":247:248 */ +// 0x00 +// /* "":244:245 */ +// 0x00 +// /* "":218:252 */ +// swap2 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul index 089892a66a..d0fc0506f8 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul @@ -4,28 +4,31 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1E -// JUMP -// JUMPDEST -// POP -// PUSH1 0x3 -// SWAP1 -// POP -// POP -// POP -// POP -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x9 -// PUSH1 0x2 -// SWAP2 -// POP -// DUP2 -// DUP2 -// MSTORE -// POP -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST +// /* "":0:80 */ +// stop +// /* "":6:78 */ +// tag_1: +// pop +// pop +// pop +// pop +// /* "":32:33 */ +// 0x00 +// /* "":6:78 */ +// swap1 +// /* "":44:45 */ +// 0x03 +// /* "":46:56 */ +// pop +// /* "":55:56 */ +// 0x09 +// /* "":57:63 */ +// swap1 +// /* "":62:63 */ +// 0x02 +// /* "":64:76 */ +// dup1 +// swap3 +// mstore +// /* "":6:78 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul index 4dde5208b4..bee0d3f635 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul @@ -4,13 +4,14 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xC -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST +// /* "":0:32 */ +// stop +// /* "":6:30 */ +// tag_1: +// /* "":25:26 */ +// 0x00 +// /* "":22:23 */ +// 0x00 +// /* "":6:30 */ +// swap2 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul index 3c1d90bd3d..5a9e7704e6 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul @@ -4,15 +4,21 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xD -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:65 */ +// stop +// /* "":6:63 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:63 */ +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":47:58 */ +// callvalue +// /* "":43:59 */ +// pop +// /* "":6:63 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul index fe99402f49..97bffac381 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul @@ -4,15 +4,20 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xD -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:65 */ +// stop +// /* "":6:63 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:63 */ +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":50:61 */ +// callvalue +// /* "":6:63 */ +// pop +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul index 7dcb39c100..c18fb7c37e 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul @@ -4,24 +4,21 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x19 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// CALLVALUE -// POP -// JUMPDEST -// PUSH1 0x0 -// ISZERO -// PUSH1 0x15 -// JUMPI -// JUMPDEST -// PUSH1 0xA -// JUMP -// JUMPDEST -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:78 */ +// stop +// /* "":6:76 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:76 */ +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":51:62 */ +// callvalue +// /* "":47:63 */ +// pop +// /* "":6:76 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul index bd882240ff..08dda5a3bc 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul @@ -4,20 +4,32 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x14 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// PUSH1 0x1 -// ISZERO -// PUSH1 0x10 -// JUMPI -// CALLVALUE -// POP -// JUMPDEST -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:70 */ +// stop +// /* "":6:68 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:68 */ +// swap1 +// /* "":44:45 */ +// 0x01 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":41:66 */ +// tag_2 +// jumpi +// /* "":24:68 */ +// tag_3: +// /* "":6:68 */ +// jump // out +// /* "":46:66 */ +// tag_2: +// /* "":52:63 */ +// callvalue +// /* "":48:64 */ +// pop +// /* "":46:66 */ +// jump(tag_3) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul index 2e16c05d58..9ac0c00bf8 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul @@ -4,17 +4,17 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x10 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// PUSH1 0xD -// JUMP -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:67 */ +// stop +// /* "":6:65 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:65 */ +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":41:46 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul index d8440b86e9..fcc8278e67 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul @@ -4,18 +4,27 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x11 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// DUP1 -// PUSH1 0x0 -// SSTORE -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:74 */ +// stop +// /* "":6:72 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:72 */ +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":41:53 */ +// dup2 +// /* "":48:49 */ +// 0x00 +// /* "":41:53 */ +// sstore +// /* "":58:69 */ +// callvalue +// /* "":54:70 */ +// pop +// /* "":6:72 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul index c20158eae3..1cc19a4641 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul @@ -4,13 +4,17 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xB -// JUMP -// JUMPDEST -// CALLVALUE -// POP -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// /* "":0:46 */ +// stop +// /* "":6:44 */ +// tag_1: +// /* "":22:23 */ +// 0x00 +// /* "":6:44 */ +// swap1 +// /* "":30:41 */ +// callvalue +// /* "":26:42 */ +// pop +// /* "":6:44 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul index d9e80547ed..e44e3b4372 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul @@ -4,17 +4,21 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x11 -// JUMP -// JUMPDEST -// CALLVALUE -// POP -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// SWAP3 -// JUMP -// JUMPDEST +// /* "":0:52 */ +// stop +// /* "":6:50 */ +// tag_1: +// /* "":25:26 */ +// 0x00 +// /* "":28:29 */ +// 0x00 +// /* "":22:23 */ +// 0x00 +// /* "":6:50 */ +// swap3 +// /* "":36:47 */ +// callvalue +// /* "":32:48 */ +// pop +// /* "":6:50 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul b/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul index 2c803e85fd..3d6286efdb 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul @@ -4,9 +4,8 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x6 -// JUMP -// JUMPDEST -// JUMPDEST -// JUMP -// JUMPDEST +// /* "":0:22 */ +// stop +// /* "":4:20 */ +// tag_1: +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul b/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul index 60f287734e..f8480bc91e 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul @@ -9,27 +9,22 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x3 -// PUSH1 0x17 -// JUMP -// JUMPDEST -// PUSH1 0x0 -// DUP2 -// POP -// PUSH1 0x3 -// SWAP2 -// POP -// DUP2 -// SWAP1 -// POP -// JUMPDEST -// SWAP3 -// SWAP2 -// POP -// POP -// JUMP -// JUMPDEST -// PUSH1 0x7 -// SWAP1 -// POP -// POP +// /* "":15:16 */ +// 0x03 +// /* "":177:183 */ +// pop +// /* "":182:183 */ +// 0x07 +// /* "":0:185 */ +// stop +// /* "":21:172 */ +// tag_1: +// swap1 +// pop +// /* "":153:159 */ +// pop +// /* "":158:159 */ +// 0x03 +// /* "":21:172 */ +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul index 6189e1614a..df8b961840 100644 --- a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul +++ b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul @@ -10,51 +10,62 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x14 -// JUMP -// JUMPDEST -// POP -// POP -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST -// PUSH1 0x1E -// PUSH1 0x2 -// PUSH1 0x1 -// PUSH1 0x3 -// JUMP -// JUMPDEST -// PUSH1 0x28 -// PUSH1 0x4 -// PUSH1 0x3 -// PUSH1 0x3 -// JUMP -// JUMPDEST -// SWAP1 -// POP -// POP -// PUSH1 0x31 -// PUSH1 0xB -// JUMP -// JUMPDEST -// PUSH1 0x37 -// PUSH1 0xB -// JUMP -// JUMPDEST -// SWAP2 -// POP -// SWAP2 -// POP -// POP -// POP -// PUSH1 0x7 -// POP +// /* "":74:81 */ +// tag_1 +// /* "":79:80 */ +// 0x02 +// /* "":76:77 */ +// 0x01 +// /* "":74:81 */ +// tag_2 +// jump // in +// tag_1: +// /* "":91:98 */ +// pop +// tag_3 +// /* "":96:97 */ +// 0x04 +// /* "":93:94 */ +// 0x03 +// /* "":91:98 */ +// tag_2 +// jump // in +// tag_3: +// /* "":115:118 */ +// pop +// tag_4 +// tag_5 +// jump // in +// tag_4: +// /* "":131:134 */ +// pop +// pop +// tag_6 +// tag_5 +// jump // in +// tag_6: +// /* "":139:154 */ +// pop +// pop +// /* "":153:154 */ +// 0x07 +// /* "":0:156 */ +// stop +// /* "":6:31 */ +// tag_2: +// pop +// pop +// /* "":26:27 */ +// 0x00 +// /* "":6:31 */ +// swap1 +// jump // out +// /* "":36:60 */ +// tag_5: +// /* "":55:56 */ +// 0x00 +// /* "":52:53 */ +// 0x00 +// /* "":36:60 */ +// swap2 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/if.yul b/test/libyul/evmCodeTransform/stackReuse/if.yul index a407bb54ce..cf0b2a044b 100644 --- a/test/libyul/evmCodeTransform/stackReuse/if.yul +++ b/test/libyul/evmCodeTransform/stackReuse/if.yul @@ -3,15 +3,22 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// MLOAD -// DUP1 -// ISZERO -// PUSH1 0xA -// JUMPI -// DUP1 -// POP -// JUMPDEST -// POP -// PUSH1 0x3 -// POP +// /* "":72:73 */ +// 0x00 +// /* "":66:74 */ +// mload +// /* "":75:94 */ +// dup1 +// tag_1 +// jumpi +// /* "":55:107 */ +// tag_2: +// /* "":95:105 */ +// pop +// /* "":104:105 */ +// 0x03 +// /* "":55:107 */ +// stop +// /* "":80:94 */ +// tag_1: +// jump(tag_2) diff --git a/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul b/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul index 1fc780d219..49ffb3971b 100644 --- a/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul +++ b/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul @@ -2,9 +2,11 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// DUP1 -// POP -// POP -// PUSH1 0x1 -// POP +// /* "":11:12 */ +// 0x00 +// /* "":15:21 */ +// pop +// /* "":33:34 */ +// 0x01 +// /* "":0:36 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul index 88d42510ca..3404dc5362 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul @@ -2,22 +2,25 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// MLOAD -// PUSH1 0x1 -// PUSH1 0x6 -// SWAP1 -// POP -// DUP1 -// SWAP2 -// POP -// POP -// PUSH1 0x2 -// DUP1 -// SWAP2 -// POP -// PUSH1 0x4 -// SWAP1 -// POP -// POP -// POP +// /* "":17:18 */ +// 0x00 +// /* "":11:19 */ +// mload +// /* "":22:32 */ +// pop +// /* "":31:32 */ +// 0x01 +// /* "":33:39 */ +// pop +// /* "":38:39 */ +// 0x06 +// /* "":51:61 */ +// pop +// /* "":60:61 */ +// 0x02 +// /* "":69:75 */ +// pop +// /* "":74:75 */ +// 0x04 +// /* "":0:79 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul index ba0ad96e7e..a80e66c10e 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul @@ -2,13 +2,19 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// PUSH1 0x6 -// SWAP1 -// POP -// POP -// PUSH1 0x2 -// PUSH1 0x4 -// SWAP1 -// POP -// POP +// /* "":11:12 */ +// 0x01 +// /* "":13:19 */ +// pop +// /* "":18:19 */ +// 0x06 +// /* "":20:30 */ +// pop +// /* "":29:30 */ +// 0x02 +// /* "":31:37 */ +// pop +// /* "":36:37 */ +// 0x04 +// /* "":0:39 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul index b064fcc20a..db87835023 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul @@ -2,13 +2,19 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// PUSH1 0x6 -// SWAP1 -// POP -// POP -// PUSH1 0x2 -// PUSH1 0x4 -// SWAP1 -// POP -// POP +// /* "":11:12 */ +// 0x01 +// /* "":13:19 */ +// pop +// /* "":18:19 */ +// 0x06 +// /* "":22:32 */ +// pop +// /* "":31:32 */ +// 0x02 +// /* "":33:39 */ +// pop +// /* "":38:39 */ +// 0x04 +// /* "":0:43 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul index fe50cb9973..9be91989d0 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul @@ -8,10 +8,10 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// DUP1 -// DUP1 -// DUP2 -// SSTORE -// POP -// POP +// /* "":15:16 */ +// 0x05 +// /* "":126:138 */ +// dup1 +// sstore +// /* "":0:146 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul index 5e4cfd0931..11e77c6269 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul @@ -6,11 +6,10 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// DUP1 -// SWAP1 -// POP -// DUP1 -// DUP2 -// SSTORE -// POP +// /* "":15:16 */ +// 0x05 +// /* "":74:86 */ +// dup1 +// sstore +// /* "":0:88 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul index 89a82f65c5..214020ccdc 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul @@ -6,13 +6,14 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// PUSH1 0x2 -// DUP2 -// ADD -// SWAP1 -// POP -// DUP1 -// DUP2 -// SSTORE -// POP +// /* "":37:38 */ +// 0x02 +// /* "":15:16 */ +// 0x05 +// /* "":30:39 */ +// add +// /* "":82:94 */ +// dup1 +// sstore +// /* "":0:96 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul index 7c7cdfd558..e3002f34d9 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul @@ -6,10 +6,11 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// DUP1 -// DUP2 -// DUP2 -// SSTORE -// POP -// POP +// /* "":15:16 */ +// 0x05 +// /* "":21:31 */ +// dup1 +// /* "":107:119 */ +// sstore +// /* "":0:121 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul index 44b9166703..13decd3231 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul @@ -2,22 +2,26 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// POP -// PUSH1 0x2 -// SWAP2 -// POP -// PUSH1 0x3 -// DUP4 -// DUP4 -// MSTORE -// DUP2 -// DUP2 -// MSTORE -// POP -// POP -// POP -// POP +// /* "":2:16 */ +// 0x00 +// dup1 +// dup1 +// dup1 +// /* "":17:27 */ +// pop +// swap2 +// swap1 +// pop +// /* "":26:27 */ +// 0x02 +// /* "":28:38 */ +// swap1 +// /* "":37:38 */ +// 0x03 +// /* "":39:51 */ +// swap2 +// mstore +// /* "":52:64 */ +// mstore +// /* "":0:66 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul index f5e855a464..a7a8b1a02c 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul @@ -5,36 +5,39 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x12 -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// SWAP3 -// SWAP4 -// JUMP -// JUMPDEST -// PUSH1 0x18 -// PUSH1 0x3 -// JUMP -// JUMPDEST -// POP -// PUSH1 0x2 -// SWAP2 -// POP -// PUSH1 0x3 -// DUP4 -// DUP4 -// MSTORE -// DUP2 -// DUP2 -// MSTORE -// POP -// POP -// POP -// POP +// /* "":58:61 */ +// tag_1 +// tag_2 +// jump // in +// tag_1: +// /* "":62:73 */ +// pop +// swap2 +// swap1 +// pop +// /* "":72:73 */ +// 0x02 +// /* "":74:85 */ +// swap1 +// /* "":84:85 */ +// 0x03 +// /* "":86:99 */ +// swap2 +// mstore +// /* "":100:113 */ +// mstore +// /* "":0:115 */ +// stop +// /* "":6:35 */ +// tag_2: +// /* "":25:26 */ +// 0x00 +// /* "":28:29 */ +// 0x00 +// /* "":31:32 */ +// 0x00 +// /* "":22:23 */ +// 0x00 +// /* "":6:35 */ +// swap4 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul index 36800b2042..888bccf7d3 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul @@ -9,42 +9,41 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// PUSH1 0x6 -// PUSH1 0x7 -// DUP2 -// DUP4 -// MSTORE -// PUSH1 0x1B -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// SWAP3 -// SWAP4 -// JUMP -// JUMPDEST -// PUSH1 0x21 -// PUSH1 0xC -// JUMP -// JUMPDEST -// SWAP6 -// POP -// SWAP4 -// POP -// POP -// DUP1 -// DUP3 -// MSTORE -// POP -// POP -// DUP2 -// DUP2 -// MSTORE -// POP -// POP +// /* "":106:107 */ +// 0x05 +// /* "":118:119 */ +// 0x06 +// /* "":130:131 */ +// 0x07 +// /* "":136:150 */ +// swap2 +// mstore +// /* "":207:210 */ +// tag_1 +// tag_2 +// jump // in +// tag_1: +// /* "":211:224 */ +// swap4 +// swap1 +// swap3 +// swap2 +// pop +// mstore +// /* "":225:237 */ +// mstore +// /* "":0:239 */ +// stop +// /* "":155:184 */ +// tag_2: +// /* "":174:175 */ +// 0x00 +// /* "":177:178 */ +// 0x00 +// /* "":180:181 */ +// 0x00 +// /* "":171:172 */ +// 0x00 +// /* "":155:184 */ +// swap4 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul index badcc0969a..2adfe7892b 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_too_deep_slot.yul @@ -33,78 +33,108 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x7 -// PUSH1 0x42 -// DUP16 -// PUSH1 0x0 -// SSTORE -// PUSH1 0x43 -// DUP2 -// PUSH1 0x1 -// MSTORE -// DUP1 -// PUSH1 0x1 -// MSTORE -// POP -// POP -// DUP15 -// PUSH1 0x1 -// SSTORE -// DUP14 -// PUSH1 0x1 -// SSTORE -// DUP13 -// PUSH1 0x1 -// SSTORE -// DUP12 -// PUSH1 0x1 -// SSTORE -// DUP11 -// PUSH1 0x1 -// SSTORE -// DUP10 -// PUSH1 0x1 -// SSTORE -// DUP9 -// PUSH1 0x1 -// SSTORE -// DUP8 -// PUSH1 0x1 -// SSTORE -// DUP7 -// PUSH1 0x1 -// SSTORE -// DUP6 -// PUSH1 0x1 -// SSTORE -// DUP5 -// PUSH1 0x1 -// SSTORE -// DUP4 -// PUSH1 0x1 -// SSTORE -// DUP3 -// PUSH1 0x1 -// SSTORE -// DUP2 -// PUSH1 0x1 -// SSTORE -// DUP1 -// PUSH1 0x1 -// SSTORE -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP -// POP +// /* "":15:16 */ +// 0x07 +// /* "":94:121 */ +// verbatimbytecode_6042 +// /* "":280:291 */ +// swap15 +// /* "":287:288 */ +// 0x00 +// /* "":280:291 */ +// swap15 +// swap2 +// swap15 +// swap14 +// swap3 +// swap14 +// swap13 +// swap4 +// swap13 +// swap12 +// swap5 +// swap12 +// swap11 +// swap6 +// swap11 +// swap10 +// swap7 +// swap10 +// swap9 +// swap8 +// swap9 +// sstore +// /* "":370:396 */ +// verbatimbytecode_6043 +// /* "":514:527 */ +// swap1 +// /* "":521:522 */ +// 0x01 +// /* "":514:527 */ +// mstore +// /* "":539:540 */ +// 0x01 +// /* "":532:545 */ +// mstore +// /* "":653:654 */ +// 0x01 +// /* "":646:659 */ +// sstore +// /* "":671:672 */ +// 0x01 +// /* "":664:677 */ +// sstore +// /* "":689:690 */ +// 0x01 +// /* "":682:695 */ +// sstore +// /* "":707:708 */ +// 0x01 +// /* "":700:713 */ +// sstore +// /* "":725:726 */ +// 0x01 +// /* "":718:731 */ +// sstore +// /* "":743:744 */ +// 0x01 +// /* "":736:749 */ +// sstore +// /* "":761:762 */ +// 0x01 +// /* "":754:767 */ +// sstore +// /* "":779:780 */ +// 0x01 +// /* "":772:785 */ +// sstore +// /* "":797:798 */ +// 0x01 +// /* "":790:803 */ +// sstore +// /* "":815:816 */ +// 0x01 +// /* "":808:822 */ +// sstore +// /* "":834:835 */ +// 0x01 +// /* "":827:841 */ +// sstore +// /* "":853:854 */ +// 0x01 +// /* "":846:860 */ +// sstore +// /* "":872:873 */ +// 0x01 +// /* "":865:879 */ +// sstore +// /* "":891:892 */ +// 0x01 +// /* "":884:898 */ +// sstore +// /* "":910:911 */ +// 0x01 +// /* "":903:917 */ +// sstore +// /* "":0:919 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var.yul b/test/libyul/evmCodeTransform/stackReuse/single_var.yul index 06957305e7..09a0d6feeb 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var.yul @@ -2,5 +2,7 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// POP +// /* "":2:7 */ +// 0x00 +// /* "":0:9 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul index 6bc5f504f2..ed497467d5 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul @@ -2,5 +2,7 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// POP +// /* "":11:12 */ +// 0x01 +// /* "":0:14 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul index 9fdccea853..bec4c834ff 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul @@ -2,8 +2,15 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// POP -// PUSH1 0x4 -// PUSH1 0x3 -// MSTORE +// /* "":11:12 */ +// 0x01 +// /* "":13:25 */ +// pop +// /* "":23:24 */ +// 0x04 +// /* "":20:21 */ +// 0x03 +// /* "":13:25 */ +// mstore +// /* "":0:27 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul index 2d66c74db7..b9a814700a 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul @@ -2,11 +2,17 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// PUSH1 0x4 -// PUSH1 0x3 -// MSTORE -// DUP1 -// MLOAD -// POP -// POP +// /* "":11:12 */ +// 0x01 +// /* "":23:24 */ +// 0x04 +// /* "":20:21 */ +// 0x03 +// /* "":13:25 */ +// mstore +// /* "":30:38 */ +// mload +// /* "":26:39 */ +// pop +// /* "":0:41 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/smoke.yul b/test/libyul/evmCodeTransform/stackReuse/smoke.yul index 0a212e9ca6..aa46f7a4a5 100644 --- a/test/libyul/evmCodeTransform/stackReuse/smoke.yul +++ b/test/libyul/evmCodeTransform/stackReuse/smoke.yul @@ -2,3 +2,5 @@ // ==== // stackOptimization: true // ---- +// /* "":0:2 */ +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/switch.yul b/test/libyul/evmCodeTransform/stackReuse/switch.yul index 480343dcc3..f72d80fad0 100644 --- a/test/libyul/evmCodeTransform/stackReuse/switch.yul +++ b/test/libyul/evmCodeTransform/stackReuse/switch.yul @@ -2,25 +2,34 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// DUP1 -// PUSH1 0x0 -// DUP2 -// EQ -// PUSH1 0x11 -// JUMPI -// PUSH1 0x3 -// SWAP2 -// POP -// PUSH1 0x18 -// JUMP -// JUMPDEST -// PUSH1 0x2 -// POP -// PUSH1 0x3 -// POP -// JUMPDEST -// POP -// POP -// PUSH1 0x9 -// POP +// /* "":11:12 */ +// 0x00 +// /* "":27:28 */ +// 0x00 +// /* "":22:54 */ +// eq +// tag_1 +// jumpi +// /* "":13:73 */ +// tag_2: +// /* "":70:71 */ +// 0x03 +// /* "":63:73 */ +// pop +// /* "":13:73 */ +// tag_3: +// /* "":83:84 */ +// 0x09 +// /* "":13:73 */ +// stop +// /* "":29:54 */ +// tag_1: +// /* "":40:41 */ +// 0x02 +// /* "":42:52 */ +// pop +// /* "":51:52 */ +// 0x03 +// /* "":29:54 */ +// pop +// jump(tag_3) diff --git a/test/libyul/evmCodeTransform/stub.yul b/test/libyul/evmCodeTransform/stub.yul new file mode 100644 index 0000000000..a11cad44c9 --- /dev/null +++ b/test/libyul/evmCodeTransform/stub.yul @@ -0,0 +1,86 @@ +{ + fun_c() + function fun_c() + { + switch iszero(calldataload(0)) + case 0 { } + default { + if calldataload(1) + { + leave + } + if calldataload(2) + { + revert(0, 0) + } + } + revert(0, 0) + } +} +// ==== +// stackOptimization: true +// ---- +// /* "":14:21 */ +// tag_1 +// tag_2 +// jump // in +// tag_1: +// /* "":0:460 */ +// stop +// /* "":34:458 */ +// tag_2: +// /* "":108:109 */ +// 0x00 +// /* "":95:110 */ +// calldataload +// /* "":88:111 */ +// iszero +// /* "":133:134 */ +// 0x00 +// /* "":128:138 */ +// eq +// tag_3 +// jumpi +// /* "":81:415 */ +// tag_4: +// /* "":201:202 */ +// 0x01 +// /* "":188:203 */ +// calldataload +// /* "":185:277 */ +// tag_5 +// jumpi +// /* "":81:415 */ +// tag_6: +// /* "":301:316 */ +// pop +// /* "":314:315 */ +// 0x02 +// /* "":301:316 */ +// calldataload +// /* "":298:397 */ +// tag_7 +// jumpi +// /* "":81:415 */ +// tag_8: +// tag_9: +// /* "":442:443 */ +// 0x00 +// /* "":432:444 */ +// dup1 +// revert +// /* "":337:397 */ +// tag_7: +// /* "":373:374 */ +// 0x00 +// /* "":363:375 */ +// dup1 +// revert +// /* "":224:277 */ +// tag_5: +// /* "":250:255 */ +// jump // out +// /* "":135:138 */ +// tag_3: +// pop +// jump(tag_9) diff --git a/test/libyul/objectCompiler/long_object_name.yul b/test/libyul/objectCompiler/long_object_name.yul index ad8266d1e5..67ef5e4072 100644 --- a/test/libyul/objectCompiler/long_object_name.yul +++ b/test/libyul/objectCompiler/long_object_name.yul @@ -16,10 +16,14 @@ object "t" { // 0x00 // /* "source":23:147 */ // sstore +// /* "source":19:150 */ +// stop // stop // // sub_0: assembly { +// /* "source":272:274 */ +// stop // } -// Bytecode: 6000600055fe -// Opcodes: PUSH1 0x0 PUSH1 0x0 SSTORE INVALID -// SourceMappings: 33:113:0:-:0;30:1;23:124 +// Bytecode: 600160005500fe +// Opcodes: PUSH1 0x1 PUSH1 0x0 SSTORE STOP INVALID +// SourceMappings: 33:113:0:-:0;30:1;23:124;19:131 diff --git a/test/libyul/objectCompiler/nested_optimizer.yul b/test/libyul/objectCompiler/nested_optimizer.yul index e6f8b1f238..7b972286f4 100644 --- a/test/libyul/objectCompiler/nested_optimizer.yul +++ b/test/libyul/objectCompiler/nested_optimizer.yul @@ -20,22 +20,26 @@ object "a" { // Assembly: // /* "source":48:49 */ // 0x00 -// dup1 // /* "source":35:50 */ +// dup1 // calldataload // /* "source":107:127 */ // sstore +// /* "source":20:131 */ +// stop // stop // // sub_0: assembly { // /* "source":188:189 */ // 0x00 -// dup1 // /* "source":175:190 */ +// dup1 // calldataload // /* "source":253:273 */ // sstore +// /* "source":158:279 */ +// stop // } -// Bytecode: 6000803555fe -// Opcodes: PUSH1 0x0 DUP1 CALLDATALOAD SSTORE INVALID -// SourceMappings: 48:1:0:-:0;;35:15;107:20 +// Bytecode: 600080355500fe +// Opcodes: PUSH1 0x0 DUP1 CALLDATALOAD SSTORE STOP INVALID +// SourceMappings: 48:1:0:-:0;35:15;;107:20;20:111 diff --git a/test/libyul/objectCompiler/simple_optimizer.yul b/test/libyul/objectCompiler/simple_optimizer.yul index cf7658ea00..47fa6553ab 100644 --- a/test/libyul/objectCompiler/simple_optimizer.yul +++ b/test/libyul/objectCompiler/simple_optimizer.yul @@ -10,11 +10,13 @@ // Assembly: // /* "source":26:27 */ // 0x00 -// dup1 // /* "source":13:28 */ +// dup1 // calldataload // /* "source":79:99 */ // sstore -// Bytecode: 6000803555 -// Opcodes: PUSH1 0x0 DUP1 CALLDATALOAD SSTORE -// SourceMappings: 26:1:0:-:0;;13:15;79:20 +// /* "source":0:101 */ +// stop +// Bytecode: 600080355500 +// Opcodes: PUSH1 0x0 DUP1 CALLDATALOAD SSTORE STOP +// SourceMappings: 26:1:0:-:0;13:15;;79:20;0:101 diff --git a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul index ae1ca7848b..2b22055794 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul @@ -237,87 +237,85 @@ // { // mstore(0x80, 7673901602397024137095011250362199966051872585513276903826533215767972925880) // mstore(0xa0, 8489654445897228341090914135473290831551238522473825886865492707826370766375) -// let _1 := calldataload(0x04) -// let notes := add(0x04, _1) -// let m := calldataload(0x24) +// let notes := add(0x04, calldataload(0x04)) // let n := calldataload(notes) -// let _2 := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 -// let challenge := mod(calldataload(0x44), _2) -// if gt(m, n) +// if gt(calldataload(0x24), n) // { // mstore(0x00, 404) // revert(0x00, 0x20) // } // let kn := calldataload(add(calldatasize(), not(191))) -// mstore(0x2a0, caller()) +// let _1 := 0x2a0 +// mstore(_1, caller()) // mstore(0x2c0, kn) -// mstore(0x2e0, m) -// kn := mulmod(sub(_2, kn), challenge, _2) +// mstore(0x2e0, calldataload(0x24)) +// kn := mulmod(sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, kn), mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) // hashCommitments(notes, n) // let b := add(0x300, shl(7, n)) // let i := 0 // for { } lt(i, n) { i := add(i, 0x01) } // { -// let _3 := add(_1, mul(i, 0xc0)) -// let noteIndex := add(_3, 0x24) +// let noteIndex := add(add(calldataload(0x04), mul(i, 0xc0)), 0x24) // let k := 0 -// let a := calldataload(add(_3, 0x44)) -// let c := challenge -// let _4 := add(i, 0x01) -// switch eq(_4, n) +// let a := calldataload(add(add(calldataload(0x04), mul(i, 0xc0)), 0x44)) +// let c := mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// let _2 := add(i, 0x01) +// switch eq(_2, n) // case 1 { // k := kn -// if eq(m, n) { k := sub(_2, kn) } +// if eq(calldataload(0x24), n) +// { +// k := sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, kn) +// } // } // case 0 { k := calldataload(noteIndex) } // validateCommitment(noteIndex, k, a) -// switch gt(_4, m) +// switch gt(_2, calldataload(0x24)) // case 1 { -// kn := addmod(kn, sub(_2, k), _2) -// let x := mod(mload(0), _2) -// k := mulmod(k, x, _2) -// a := mulmod(a, x, _2) -// c := mulmod(challenge, x, _2) +// kn := addmod(kn, sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, k), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// let x := mod(mload(0), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// k := mulmod(k, x, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// a := mulmod(a, x, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// c := mulmod(mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), x, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) // mstore(0, keccak256(0, 0x20)) // } -// case 0 { kn := addmod(kn, k, _2) } -// let _5 := 0x40 -// calldatacopy(0xe0, add(_3, 164), _5) -// calldatacopy(0x20, add(_3, 100), _5) -// let _6 := 0x120 -// mstore(_6, sub(_2, c)) -// let _7 := 0x60 -// mstore(_7, k) +// case 0 { +// kn := addmod(kn, k, 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001) +// } +// calldatacopy(0xe0, add(add(calldataload(0x04), mul(i, 0xc0)), 164), 0x40) +// calldatacopy(0x20, add(add(calldataload(0x04), mul(i, 0xc0)), 100), 0x40) +// mstore(0x120, sub(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001, c)) +// mstore(0x60, k) // mstore(0xc0, a) -// let result := call(gas(), 7, 0, 0xe0, _7, 0x1a0, _5) -// let result_1 := and(result, call(gas(), 7, 0, 0x20, _7, _6, _5)) -// let _8 := 0x160 -// let result_2 := and(result_1, call(gas(), 7, 0, 0x80, _7, _8, _5)) -// let result_3 := and(result_2, call(gas(), 6, 0, _6, 0x80, _8, _5)) -// result := and(result_3, call(gas(), 6, 0, _8, 0x80, b, _5)) -// if eq(i, m) +// let result := call(gas(), 7, 0, 0xe0, 0x60, 0x1a0, 0x40) +// let result_1 := and(result, call(gas(), 7, 0, 0x20, 0x60, 0x120, 0x40)) +// let result_2 := and(result_1, call(gas(), 7, 0, 0x80, 0x60, 0x160, 0x40)) +// let result_3 := and(result_2, call(gas(), 6, 0, 0x120, 0x80, 0x160, 0x40)) +// result := and(result_3, call(gas(), 6, 0, 0x160, 0x80, b, 0x40)) +// if eq(i, calldataload(0x24)) // { // mstore(0x260, mload(0x20)) -// mstore(0x280, mload(_5)) +// mstore(0x280, mload(0x40)) // mstore(0x1e0, mload(0xe0)) // mstore(0x200, sub(0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, mload(0x100))) // } -// if gt(i, m) +// if gt(i, calldataload(0x24)) // { -// mstore(_7, c) -// let result_4 := and(result, call(gas(), 7, 0, 0x20, _7, 0x220, _5)) -// let result_5 := and(result_4, call(gas(), 6, 0, 0x220, 0x80, 0x260, _5)) -// result := and(result_5, call(gas(), 6, 0, 0x1a0, 0x80, 0x1e0, _5)) +// mstore(0x60, c) +// let _3 := 0x220 +// let result_4 := and(result, call(gas(), 7, 0, 0x20, 0x60, _3, 0x40)) +// let result_5 := and(result_4, call(gas(), 6, 0, _3, 0x80, 0x260, 0x40)) +// result := and(result_5, call(gas(), 6, 0, 0x1a0, 0x80, 0x1e0, 0x40)) // } // if iszero(result) // { // mstore(0, 400) // revert(0, 0x20) // } -// b := add(b, _5) +// b := add(b, 0x40) // } -// if lt(m, n) { validatePairing() } -// if iszero(eq(mod(keccak256(0x2a0, add(b, not(671))), _2), challenge)) +// if lt(calldataload(0x24), n) { validatePairing() } +// if iszero(eq(mod(keccak256(_1, add(b, not(671))), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001), mod(calldataload(0x44), 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001))) // { // mstore(0, 404) // revert(0, 0x20) diff --git a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul index b417991c27..d670f002fc 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul @@ -33,25 +33,30 @@ sstore(0,0) sstore(3,1) } +// ==== +// EVMVersion: >homestead // ---- // step: fullSuite // // { // { -// let _1 := gt(not(gcd(10, 15)), 1) -// let _2 := gcd(10, 15) -// let _3 := not(0) -// let _4 := lt(or(1, add(gcd(10, 15), _3)), 1) -// let _5 := gcd(10, 15) -// let _6 := gcd(10, 15) -// pop(keccak256(gcd(10, 15), or(gt(not(gcd(10, 15)), 1), 1))) -// mstore(lt(or(gt(1, or(or(gt(or(or(or(gt(or(gt(_3, _6), 1), _5), _4), _2), 1), 1), _1), 1)), 1), 1), 1) -// sstore(not(gcd(10, 15)), 1) +// let _1 := 1 +// let _2 := 15 +// let _3 := 10 +// let _4 := gt(not(gcd(_3, _2)), _1) +// let _5 := gcd(_3, _2) +// let _6 := not(0) +// let _7 := lt(or(_1, add(gcd(_3, _2), _6)), _1) +// let _8 := gcd(_3, _2) +// let _9 := gcd(_3, _2) +// pop(keccak256(gcd(_3, _2), or(gt(not(gcd(_3, _2)), _1), _1))) +// mstore(lt(or(gt(_1, or(or(gt(or(or(or(gt(or(gt(_6, _9), _1), _8), _7), _5), _1), _1), _4), _1)), _1), _1), _1) +// sstore(not(gcd(_3, _2)), _1) // sstore(0, 0) -// sstore(2, 1) -// extcodecopy(1, msize(), 1, 1) +// sstore(2, _1) +// extcodecopy(_1, msize(), _1, _1) // sstore(0, 0) -// sstore(3, 1) +// sstore(3, _1) // } // function gcd(_a, _b) -> out // { diff --git a/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul b/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul index 4ff0561571..382bd201d6 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul @@ -3,6 +3,8 @@ let y := calldataload(calldataload(9)) mstore(y, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(y, 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)) } +// ==== +// EVMVersion: =homestead // ---- // step: stackCompressor // diff --git a/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul b/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul index f237ea8bbc..ed85fe7b85 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul @@ -5,6 +5,8 @@ mstore(y, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(y, 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)) } } +// ==== +// EVMVersion: =homestead // ---- // step: stackCompressor // diff --git a/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul b/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul index 7e3acd9b62..dc10737ad9 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul @@ -18,6 +18,8 @@ extcodecopy(1, msize(), 1, 1) } } +// ==== +// EVMVersion: =homestead // ---- // step: stackCompressor // diff --git a/test/libyul/yulStackLayout/literal_loop.yul b/test/libyul/yulStackLayout/literal_loop.yul new file mode 100644 index 0000000000..841c410626 --- /dev/null +++ b/test/libyul/yulStackLayout/literal_loop.yul @@ -0,0 +1,69 @@ +{ + for {} + add(delegatecall(delegatecall(call(gas(), 0x0, 0x0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0x0, 0x0, 0x0),0x0) + {} + {} +} +// ---- +// digraph CFG { +// nodesep=0.7; +// node[shape=box]; +// +// Entry [label="Entry"]; +// Entry -> Block0; +// Block0 [label="\ +// [ ]\l\ +// [ ]\l\ +// "]; +// Block0 -> Block0Exit [arrowhead=none]; +// Block0Exit [label="Jump" shape=oval]; +// Block0Exit -> Block1; +// +// Block1 [label="\ +// [ ]\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ]\l\ +// gas\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 TMP[gas, 0] ]\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 TMP[gas, 0] ]\l\ +// call\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 TMP[call, 0] ]\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 TMP[call, 0] ]\l\ +// delegatecall\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 TMP[delegatecall, 0] ]\l\ +// [ 0x00 0x00 0x00 0x00 0x00 0x00 TMP[delegatecall, 0] ]\l\ +// delegatecall\l\ +// [ 0x00 TMP[delegatecall, 0] ]\l\ +// [ 0x00 TMP[delegatecall, 0] ]\l\ +// add\l\ +// [ TMP[add, 0] ]\l\ +// [ TMP[add, 0] ]\l\ +// "]; +// Block1 -> Block1Exit; +// Block1Exit [label="{ TMP[add, 0]| { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1Exit:0 -> Block2; +// Block1Exit:1 -> Block3; +// +// Block2 [label="\ +// [ ]\l\ +// [ ]\l\ +// "]; +// Block2Exit [label="MainExit"]; +// Block2 -> Block2Exit; +// +// Block3 [label="\ +// [ ]\l\ +// [ ]\l\ +// "]; +// Block3 -> Block3Exit [arrowhead=none]; +// Block3Exit [label="Jump" shape=oval]; +// Block3Exit -> Block4; +// +// Block4 [label="\ +// [ ]\l\ +// [ ]\l\ +// "]; +// Block4 -> Block4Exit [arrowhead=none]; +// Block4Exit [label="BackwardsJump" shape=oval]; +// Block4Exit -> Block1; +// +// } From 28ae31655651512575d816dd898e22051db158f0 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 1 Nov 2021 14:19:33 +0100 Subject: [PATCH 0062/1748] Named function labels. --- libyul/backends/evm/EVMObjectCompiler.cpp | 10 +- .../evm/OptimizedEVMCodeTransform.cpp | 38 +- .../backends/evm/OptimizedEVMCodeTransform.h | 12 +- .../function_debug_info_via_yul/output | 15 +- .../output.json | 360 +++++++++--------- .../stackReuse/function_call.yul | 10 +- .../stackReuse/functions_multi_return.yul | 22 +- .../stackReuse/reuse_slots_function.yul | 6 +- .../reuse_slots_function_with_gaps.yul | 6 +- test/libyul/evmCodeTransform/stub.yul | 6 +- 10 files changed, 260 insertions(+), 225 deletions(-) diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index c85c1ae921..bede32d174 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -65,8 +65,14 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) yulAssert(_object.code, "No code."); if (_optimize && m_dialect.evmVersion().canOverchargeGasForCall()) { - - auto stackErrors = OptimizedEVMCodeTransform::run(m_assembly, *_object.analysisInfo, *_object.code, m_dialect, context); + auto stackErrors = OptimizedEVMCodeTransform::run( + m_assembly, + *_object.analysisInfo, + *_object.code, + m_dialect, + context, + OptimizedEVMCodeTransform::UseNamedLabels::ForFirstFunctionOfEachName + ); if (!stackErrors.empty()) BOOST_THROW_EXCEPTION(stackErrors.front()); } diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index ca57c59d27..08987b5654 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -44,7 +44,7 @@ vector OptimizedEVMCodeTransform::run( Block const& _block, EVMDialect const& _dialect, BuiltinContext& _builtinContext, - bool _useNamedLabelsForFunctions + UseNamedLabels _useNamedLabelsForFunctions ) { std::unique_ptr dfg = ControlFlowGraphBuilder::build(_analysisInfo, _dialect, _block); @@ -170,15 +170,35 @@ void OptimizedEVMCodeTransform::operator()(CFG::Assignment const& _assignment) OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( AbstractAssembly& _assembly, BuiltinContext& _builtinContext, - bool _useNamedLabelsForFunctions, + UseNamedLabels _useNamedLabelsForFunctions, CFG const& _dfg, StackLayout const& _stackLayout ): m_assembly(_assembly), m_builtinContext(_builtinContext), - m_useNamedLabelsForFunctions(_useNamedLabelsForFunctions), m_dfg(_dfg), - m_stackLayout(_stackLayout) + m_stackLayout(_stackLayout), + m_functionLabels([&](){ + map functionLabels; + set assignedFunctionNames; + for (Scope::Function const* function: m_dfg.functions) + { + CFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(function); + bool nameAlreadySeen = !assignedFunctionNames.insert(function->name).second; + if (_useNamedLabelsForFunctions == UseNamedLabels::YesAndForceUnique) + yulAssert(!nameAlreadySeen); + bool useNamedLabel = _useNamedLabelsForFunctions != UseNamedLabels::Never && !nameAlreadySeen; + functionLabels[&functionInfo] = useNamedLabel ? + m_assembly.namedLabel( + function->name.str(), + function->arguments.size(), + function->returns.size(), + functionInfo.debugData ? functionInfo.debugData->astID : nullopt + ) : + m_assembly.newLabelId(); + } + return functionLabels; + }()) { } @@ -191,15 +211,7 @@ void OptimizedEVMCodeTransform::assertLayoutCompatibility(Stack const& _currentS AbstractAssembly::LabelID OptimizedEVMCodeTransform::getFunctionLabel(Scope::Function const& _function) { - CFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(&_function); - if (!m_functionLabels.count(&functionInfo)) - m_functionLabels[&functionInfo] = m_useNamedLabelsForFunctions ? m_assembly.namedLabel( - functionInfo.function.name.str(), - functionInfo.function.arguments.size(), - functionInfo.function.returns.size(), - {} - ) : m_assembly.newLabelId(); - return m_functionLabels[&functionInfo]; + return m_functionLabels.at(&m_dfg.functionInfo.at(&_function)); } void OptimizedEVMCodeTransform::validateSlot(StackSlot const& _slot, Expression const& _expression) diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.h b/libyul/backends/evm/OptimizedEVMCodeTransform.h index 48819251ae..ed03c14530 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.h +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.h @@ -43,13 +43,17 @@ struct StackLayout; class OptimizedEVMCodeTransform { public: + /// Use named labels for functions 1) Yes and check that the names are unique + /// 2) For none of the functions 3) for the first function of each name. + enum class UseNamedLabels { YesAndForceUnique, Never, ForFirstFunctionOfEachName }; + [[nodiscard]] static std::vector run( AbstractAssembly& _assembly, AsmAnalysisInfo& _analysisInfo, Block const& _block, EVMDialect const& _dialect, BuiltinContext& _builtinContext, - bool _useNamedLabelsForFunctions = false + UseNamedLabels _useNamedLabelsForFunctions ); /// Generate code for the function call @a _call. Only public for using with std::visit. @@ -62,7 +66,7 @@ class OptimizedEVMCodeTransform OptimizedEVMCodeTransform( AbstractAssembly& _assembly, BuiltinContext& _builtinContext, - bool _useNamedLabelsForFunctions, + UseNamedLabels _useNamedLabelsForFunctions, CFG const& _dfg, StackLayout const& _stackLayout ); @@ -70,6 +74,7 @@ class OptimizedEVMCodeTransform /// Assert that it is valid to transition from @a _currentStack to @a _desiredStack. /// That is @a _currentStack matches each slot in @a _desiredStack that is not a JunkSlot exactly. static void assertLayoutCompatibility(Stack const& _currentStack, Stack const& _desiredStack); + /// @returns The label of the entry point of the given @a _function. /// Creates and stores a new label, if none exists already. AbstractAssembly::LabelID getFunctionLabel(Scope::Function const& _function); @@ -94,13 +99,12 @@ class OptimizedEVMCodeTransform AbstractAssembly& m_assembly; BuiltinContext& m_builtinContext; - bool m_useNamedLabelsForFunctions = true; CFG const& m_dfg; StackLayout const& m_stackLayout; Stack m_stack; std::map m_returnLabels; std::map m_blockLabels; - std::map m_functionLabels; + std::map const m_functionLabels; /// Set of blocks already generated. If any of the contained blocks is ever jumped to, m_blockLabels should /// contain a jump label for it. std::set m_generated; diff --git a/test/cmdlineTests/function_debug_info_via_yul/output b/test/cmdlineTests/function_debug_info_via_yul/output index 5af245ce4a..495c82d5be 100644 --- a/test/cmdlineTests/function_debug_info_via_yul/output +++ b/test/cmdlineTests/function_debug_info_via_yul/output @@ -4,7 +4,20 @@ "function_debug_info_via_yul/input.sol:C": { "function-debug": {}, - "function-debug-runtime": {} + "function-debug-runtime": + { + "abi_encode_uint256": + { + "parameterSlots": 2, + "returnSlots": 1 + }, + "calldata_array_index_access_uint256_dyn_calldata": + { + "entryPoint": 152, + "parameterSlots": 2, + "returnSlots": 1 + } + } } }, "version": "" diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json index d8877a82ba..0c529109ae 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json @@ -3,7 +3,7 @@ dup1 0x40 mstore - jumpi(tag_5, callvalue) + jumpi(tag_6, callvalue) 0x1f bytecodeSize codesize @@ -25,7 +25,7 @@ dup5 lt or - tag_3 + tag_4 jumpi dup1 dup5 @@ -40,7 +40,7 @@ add sub slt - tag_5 + tag_6 jumpi mload /* \"C\":147:149 42 */ @@ -60,12 +60,12 @@ dup2 assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") return -tag_5: +tag_6: pop 0x00 dup1 revert -tag_3: +tag_4: pop pop pop @@ -78,11 +78,11 @@ stop sub_0: assembly { /* \"C\":79:428 contract C... */ mstore(0x40, 0x80) - jumpi(tag_1, iszero(lt(calldatasize, 0x04))) + jumpi(tag_8, iszero(lt(calldatasize, 0x04))) 0x00 dup1 revert - tag_1: + tag_8: 0x00 dup1 calldataload @@ -91,35 +91,35 @@ sub_0: assembly { dup1 0x26121ff0 eq - tag_3 + tag_10 jumpi dup1 0x793816ec eq - tag_5 + tag_12 jumpi 0x9942ec6f eq - tag_7 + tag_14 jumpi pop 0x00 dup1 revert - tag_7: - jumpi(tag_9, callvalue) + tag_14: + jumpi(tag_16, callvalue) pop - tag_11 + tag_18 calldatasize - tag_12 + tag_1 jump\t// in - tag_11: - tag_13 + tag_18: + tag_19 /* \"C\":375:378 int */ - tag_14 - tag_15 + tag_20 + tag_6 jump\t// in - tag_14: + tag_20: /* \"C\":79:428 contract C... */ mload(0x40) swap1 @@ -133,23 +133,23 @@ sub_0: assembly { add swap1 jump - tag_13: + tag_19: sub swap1 return - tag_9: + tag_16: dup1 revert - tag_5: + tag_12: pop - jumpi(tag_9, callvalue) - tag_13 + jumpi(tag_16, callvalue) + tag_19 swap1 - tag_20 + tag_24 calldatasize - tag_12 + tag_1 jump\t// in - tag_20: + tag_24: sload mload(0x40) swap1 @@ -163,64 +163,64 @@ sub_0: assembly { add swap1 jump - tag_3: + tag_10: pop - jumpi(tag_9, callvalue) + jumpi(tag_16, callvalue) pop - tag_23 + tag_27 calldatasize - tag_12 + tag_1 jump\t// in - tag_23: - tag_13 + tag_27: + tag_19 /* \"C\":279:298 constVar + immutVar */ - tag_14 + tag_20 /* \"C\":290:298 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":279:298 constVar + immutVar */ - tag_26 + tag_4 jump\t// in /* \"C\":79:428 contract C... */ - tag_12: + tag_1: 0x00 swap1 not(0x03) add slt - tag_27 + tag_30 jumpi jump\t// out - tag_27: + tag_30: pop 0x00 dup1 revert /* \"C\":117:119 41 */ - tag_29: + tag_3: pop mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x11) revert(0x00, 0x24) - tag_26: + tag_4: sub(shl(0xff, 0x01), 0x2a) dup2 sgt 0x01 and - tag_30 + tag_32 jumpi - tag_31: + tag_33: 0x29 add swap1 jump\t// out - tag_30: - tag_32 - tag_29 - jump\t// in tag_32: - jump(tag_31) - tag_33: + tag_34 + tag_3 + jump\t// in + tag_34: + jump(tag_33) + tag_5: 0x00 dup2 slt @@ -233,9 +233,9 @@ sub_0: assembly { dup5 sgt and - tag_34 + tag_35 jumpi - tag_35: + tag_36: shl(0xff, 0x01) dup3 swap1 @@ -243,27 +243,27 @@ sub_0: assembly { dup4 slt and - tag_36 + tag_37 jumpi add swap1 jump\t// out - tag_36: - tag_38 - tag_29 + tag_37: + tag_39 + tag_3 jump\t// in - tag_38: + tag_39: add swap1 jump\t// out - tag_34: - tag_39 - tag_29 + tag_35: + tag_40 + tag_3 jump\t// in - tag_39: - jump(tag_35) + tag_40: + jump(tag_36) /* \"C\":304:341 modifier m()... */ - tag_15: + tag_6: /* \"C\":79:428 contract C... */ 0x00 dup1 @@ -275,10 +275,10 @@ sub_0: assembly { /* \"C\":79:428 contract C... */ dup2 eq - tag_40 + tag_41 jumpi /* \"C\":304:341 modifier m()... */ - tag_41: + tag_42: /* \"C\":79:428 contract C... */ add swap1 @@ -290,7 +290,7 @@ sub_0: assembly { /* \"C\":403:411 this.f() */ extcodesize iszero - tag_42 + tag_43 jumpi /* \"C\":79:428 contract C... */ mload(0x40) @@ -313,38 +313,38 @@ sub_0: assembly { swap2 dup3 iszero - tag_44 + tag_45 jumpi dup1 swap3 - tag_46 + tag_47 jumpi /* \"C\":304:341 modifier m()... */ - tag_47: + tag_48: /* \"C\":392:411 stateVar + this.f() */ pop pop - tag_48 + tag_49 swap1 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_49 + tag_50 /* \"C\":392:411 stateVar + this.f() */ swap3 - tag_33 + tag_5 jump\t// in - tag_48: + tag_49: /* \"C\":414:422 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":392:422 stateVar + this.f() + immutVar */ swap1 - tag_33 + tag_5 jump\t// in - tag_49: + tag_50: /* \"C\":304:341 modifier m()... */ swap1 jump\t// out /* \"C\":403:411 this.f() */ - tag_46: + tag_47: /* \"C\":79:428 contract C... */ swap1 swap2 @@ -366,18 +366,18 @@ sub_0: assembly { dup4 lt or - tag_50 + tag_51 jumpi pop swap2 /* \"C\":403:411 this.f() */ - tag_52 + tag_53 /* \"C\":392:411 stateVar + this.f() */ - tag_48 + tag_49 /* \"C\":79:428 contract C... */ swap3 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_49 + tag_50 /* \"C\":79:428 contract C... */ swap5 0x40 @@ -387,16 +387,16 @@ sub_0: assembly { dup2 add swap1 - tag_53 + tag_7 jump\t// in - tag_52: + tag_53: swap2 dup2 swap4 pop - jump(tag_47) + jump(tag_48) /* \"C\":79:428 contract C... */ - tag_50: + tag_51: shl(0xe0, 0x4e487b71) dup2 mstore @@ -416,7 +416,7 @@ sub_0: assembly { /* \"C\":79:428 contract C... */ revert /* \"C\":403:411 this.f() */ - tag_44: + tag_45: /* \"C\":79:428 contract C... */ swap4 pop @@ -433,20 +433,20 @@ sub_0: assembly { swap1 revert /* \"C\":403:411 this.f() */ - tag_42: + tag_43: /* \"C\":79:428 contract C... */ swap2 pop pop dup1 revert - tag_40: + tag_41: tag_54 - tag_29 + tag_3 jump\t// in tag_54: - jump(tag_41) - tag_53: + jump(tag_42) + tag_7: swap1 dup2 0x20 @@ -472,7 +472,7 @@ sub_0: assembly { dup1 0x40 mstore - jumpi(tag_5, callvalue) + jumpi(tag_6, callvalue) 0x1f bytecodeSize codesize @@ -494,7 +494,7 @@ sub_0: assembly { dup5 lt or - tag_3 + tag_4 jumpi dup1 dup5 @@ -509,14 +509,14 @@ sub_0: assembly { add sub slt - tag_5 + tag_6 jumpi - tag_7 + tag_8 swap1 mload - tag_8 + tag_1 jump\t// in -tag_7: +tag_8: mload(0x40) dataSize(sub_0) swap1 @@ -528,12 +528,12 @@ tag_7: dup2 assignImmutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") return -tag_5: +tag_6: pop 0x00 dup1 revert -tag_3: +tag_4: pop pop pop @@ -542,7 +542,7 @@ tag_3: mstore(0x04, 0x41) revert(0x00, 0x24) /* \"D\":113:164 constructor(int _init2)... */ -tag_8: +tag_1: /* \"C\":147:149 42 */ mstore(0x80, 0x2a) /* \"D\":107:108 3 */ @@ -588,11 +588,11 @@ stop sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ mstore(0x40, 0x80) - jumpi(tag_1, iszero(lt(calldatasize, 0x04))) + jumpi(tag_8, iszero(lt(calldatasize, 0x04))) 0x00 dup1 revert - tag_1: + tag_8: 0x00 dup1 calldataload @@ -601,35 +601,35 @@ sub_0: assembly { dup1 0x26121ff0 eq - tag_3 + tag_10 jumpi dup1 0x793816ec eq - tag_5 + tag_12 jumpi 0x9942ec6f eq - tag_7 + tag_14 jumpi pop 0x00 dup1 revert - tag_7: - jumpi(tag_9, callvalue) + tag_14: + jumpi(tag_16, callvalue) pop - tag_11 + tag_18 calldatasize - tag_12 + tag_1 jump\t// in - tag_11: - tag_13 + tag_18: + tag_19 /* \"C\":375:378 int */ - tag_14 - tag_15 + tag_20 + tag_6 jump\t// in - tag_14: + tag_20: /* \"D\":91:166 contract D is C(3)... */ mload(0x40) swap1 @@ -643,23 +643,23 @@ sub_0: assembly { add swap1 jump - tag_13: + tag_19: sub swap1 return - tag_9: + tag_16: dup1 revert - tag_5: + tag_12: pop - jumpi(tag_9, callvalue) - tag_13 + jumpi(tag_16, callvalue) + tag_19 swap1 - tag_20 + tag_24 calldatasize - tag_12 + tag_1 jump\t// in - tag_20: + tag_24: sload mload(0x40) swap1 @@ -673,64 +673,64 @@ sub_0: assembly { add swap1 jump - tag_3: + tag_10: pop - jumpi(tag_9, callvalue) + jumpi(tag_16, callvalue) pop - tag_23 + tag_27 calldatasize - tag_12 + tag_1 jump\t// in - tag_23: - tag_13 + tag_27: + tag_19 /* \"C\":279:298 constVar + immutVar */ - tag_14 + tag_20 /* \"C\":290:298 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":279:298 constVar + immutVar */ - tag_26 + tag_4 jump\t// in /* \"D\":91:166 contract D is C(3)... */ - tag_12: + tag_1: 0x00 swap1 not(0x03) add slt - tag_27 + tag_30 jumpi jump\t// out - tag_27: + tag_30: pop 0x00 dup1 revert /* \"C\":117:119 41 */ - tag_29: + tag_3: pop mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, 0x11) revert(0x00, 0x24) - tag_26: + tag_4: sub(shl(0xff, 0x01), 0x2a) dup2 sgt 0x01 and - tag_30 + tag_32 jumpi - tag_31: + tag_33: 0x29 add swap1 jump\t// out - tag_30: - tag_32 - tag_29 - jump\t// in tag_32: - jump(tag_31) - tag_33: + tag_34 + tag_3 + jump\t// in + tag_34: + jump(tag_33) + tag_5: 0x00 dup2 slt @@ -743,9 +743,9 @@ sub_0: assembly { dup5 sgt and - tag_34 + tag_35 jumpi - tag_35: + tag_36: shl(0xff, 0x01) dup3 swap1 @@ -753,27 +753,27 @@ sub_0: assembly { dup4 slt and - tag_36 + tag_37 jumpi add swap1 jump\t// out - tag_36: - tag_38 - tag_29 + tag_37: + tag_39 + tag_3 jump\t// in - tag_38: + tag_39: add swap1 jump\t// out - tag_34: - tag_39 - tag_29 + tag_35: + tag_40 + tag_3 jump\t// in - tag_39: - jump(tag_35) + tag_40: + jump(tag_36) /* \"C\":304:341 modifier m()... */ - tag_15: + tag_6: /* \"D\":91:166 contract D is C(3)... */ 0x00 dup1 @@ -785,10 +785,10 @@ sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ dup2 eq - tag_40 + tag_41 jumpi /* \"C\":304:341 modifier m()... */ - tag_41: + tag_42: /* \"D\":91:166 contract D is C(3)... */ add swap1 @@ -800,7 +800,7 @@ sub_0: assembly { /* \"C\":403:411 this.f() */ extcodesize iszero - tag_42 + tag_43 jumpi /* \"D\":91:166 contract D is C(3)... */ mload(0x40) @@ -823,38 +823,38 @@ sub_0: assembly { swap2 dup3 iszero - tag_44 + tag_45 jumpi dup1 swap3 - tag_46 + tag_47 jumpi /* \"C\":304:341 modifier m()... */ - tag_47: + tag_48: /* \"C\":392:411 stateVar + this.f() */ pop pop - tag_48 + tag_49 swap1 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_49 + tag_50 /* \"C\":392:411 stateVar + this.f() */ swap3 - tag_33 + tag_5 jump\t// in - tag_48: + tag_49: /* \"C\":414:422 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":392:422 stateVar + this.f() + immutVar */ swap1 - tag_33 + tag_5 jump\t// in - tag_49: + tag_50: /* \"C\":304:341 modifier m()... */ swap1 jump\t// out /* \"C\":403:411 this.f() */ - tag_46: + tag_47: /* \"D\":91:166 contract D is C(3)... */ swap1 swap2 @@ -876,18 +876,18 @@ sub_0: assembly { dup4 lt or - tag_50 + tag_51 jumpi pop swap2 /* \"C\":403:411 this.f() */ - tag_52 + tag_53 /* \"C\":392:411 stateVar + this.f() */ - tag_48 + tag_49 /* \"D\":91:166 contract D is C(3)... */ swap3 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_49 + tag_50 /* \"D\":91:166 contract D is C(3)... */ swap5 0x40 @@ -897,16 +897,16 @@ sub_0: assembly { dup2 add swap1 - tag_53 + tag_7 jump\t// in - tag_52: + tag_53: swap2 dup2 swap4 pop - jump(tag_47) + jump(tag_48) /* \"D\":91:166 contract D is C(3)... */ - tag_50: + tag_51: shl(0xe0, 0x4e487b71) dup2 mstore @@ -926,7 +926,7 @@ sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ revert /* \"C\":403:411 this.f() */ - tag_44: + tag_45: /* \"D\":91:166 contract D is C(3)... */ swap4 pop @@ -943,20 +943,20 @@ sub_0: assembly { swap1 revert /* \"C\":403:411 this.f() */ - tag_42: + tag_43: /* \"D\":91:166 contract D is C(3)... */ swap2 pop pop dup1 revert - tag_40: + tag_41: tag_54 - tag_29 + tag_3 jump\t// in tag_54: - jump(tag_41) - tag_53: + jump(tag_42) + tag_7: swap1 dup2 0x20 diff --git a/test/libyul/evmCodeTransform/stackReuse/function_call.yul b/test/libyul/evmCodeTransform/stackReuse/function_call.yul index 1abc8d8aff..507b354413 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_call.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_call.yul @@ -7,15 +7,15 @@ // stackOptimization: true // ---- // /* "":15:22 */ -// tag_1 +// tag_2 // /* "":20:21 */ // 0x02 // /* "":17:18 */ // 0x01 // /* "":15:22 */ -// tag_2 +// tag_1 // jump // in -// tag_1: +// tag_2: // /* "":62:69 */ // pop // tag_3 @@ -24,13 +24,13 @@ // /* "":64:65 */ // 0x03 // /* "":62:69 */ -// tag_2 +// tag_1 // jump // in // tag_3: // /* "":0:71 */ // stop // /* "":27:52 */ -// tag_2: +// tag_1: // pop // pop // /* "":47:48 */ diff --git a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul index df8b961840..1ce02483dc 100644 --- a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul +++ b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul @@ -11,37 +11,37 @@ // stackOptimization: true // ---- // /* "":74:81 */ -// tag_1 +// tag_3 // /* "":79:80 */ // 0x02 // /* "":76:77 */ // 0x01 // /* "":74:81 */ -// tag_2 +// tag_1 // jump // in -// tag_1: +// tag_3: // /* "":91:98 */ // pop -// tag_3 +// tag_4 // /* "":96:97 */ // 0x04 // /* "":93:94 */ // 0x03 // /* "":91:98 */ -// tag_2 +// tag_1 // jump // in -// tag_3: +// tag_4: // /* "":115:118 */ // pop -// tag_4 // tag_5 +// tag_2 // jump // in -// tag_4: +// tag_5: // /* "":131:134 */ // pop // pop // tag_6 -// tag_5 +// tag_2 // jump // in // tag_6: // /* "":139:154 */ @@ -52,7 +52,7 @@ // /* "":0:156 */ // stop // /* "":6:31 */ -// tag_2: +// tag_1: // pop // pop // /* "":26:27 */ @@ -61,7 +61,7 @@ // swap1 // jump // out // /* "":36:60 */ -// tag_5: +// tag_2: // /* "":55:56 */ // 0x00 // /* "":52:53 */ diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul index a7a8b1a02c..13e3065ccc 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul @@ -6,10 +6,10 @@ // stackOptimization: true // ---- // /* "":58:61 */ -// tag_1 // tag_2 +// tag_1 // jump // in -// tag_1: +// tag_2: // /* "":62:73 */ // pop // swap2 @@ -29,7 +29,7 @@ // /* "":0:115 */ // stop // /* "":6:35 */ -// tag_2: +// tag_1: // /* "":25:26 */ // 0x00 // /* "":28:29 */ diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul index 888bccf7d3..f1cde362ae 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul @@ -19,10 +19,10 @@ // swap2 // mstore // /* "":207:210 */ -// tag_1 // tag_2 +// tag_1 // jump // in -// tag_1: +// tag_2: // /* "":211:224 */ // swap4 // swap1 @@ -35,7 +35,7 @@ // /* "":0:239 */ // stop // /* "":155:184 */ -// tag_2: +// tag_1: // /* "":174:175 */ // 0x00 // /* "":177:178 */ diff --git a/test/libyul/evmCodeTransform/stub.yul b/test/libyul/evmCodeTransform/stub.yul index a11cad44c9..ef7cd668c1 100644 --- a/test/libyul/evmCodeTransform/stub.yul +++ b/test/libyul/evmCodeTransform/stub.yul @@ -21,14 +21,14 @@ // stackOptimization: true // ---- // /* "":14:21 */ -// tag_1 // tag_2 +// tag_1 // jump // in -// tag_1: +// tag_2: // /* "":0:460 */ // stop // /* "":34:458 */ -// tag_2: +// tag_1: // /* "":108:109 */ // 0x00 // /* "":95:110 */ From e9708105a40845083a8ee83e03848975ea6dfb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 17:11:18 +0200 Subject: [PATCH 0063/1748] CI: Remove superfluous/unused test_ dicts --- .circleci/config.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 00c7223d5e..b53999f2a8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -219,14 +219,6 @@ defaults: parallelism: 6 <<: *steps_soltest_all - - test_asan: &test_asan - <<: *test_ubuntu2004 - <<: *steps_soltest - - - test_ubuntu2004_clang_cli: &test_ubuntu2004_clang_cli - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> - <<: *steps_cmdline_tests # -------------------------------------------------------------------------- # Workflow Templates @@ -806,7 +798,7 @@ jobs: <<: *steps_cmdline_tests t_ubu_asan: - <<: *test_asan + <<: *test_ubuntu2004 environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 From 9aafbf1092e434e4ed2491db3e1babb7cf50df99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 17:12:03 +0200 Subject: [PATCH 0064/1748] CI: Replace `test_` dicts with `base_` ones and make their steps explicit --- .circleci/config.yml | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b53999f2a8..82c860bb7b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -170,7 +170,7 @@ defaults: destination: test_results/ # -------------------------------------------------------------------------- - # Tests Templates + # Step Templates # store_test_results helper - store_test_results: &store_test_results @@ -181,6 +181,9 @@ defaults: - checkout - attach_workspace: at: build + # NOTE: Different build jobs produce different soltest executables (release/debug, + # clang/gcc, windows/linux/macos, etc.). The executable used by these steps comes from the + # attached workspace and we only see the items added to the workspace by jobs we depend on. - run: *run_soltest - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results @@ -203,22 +206,20 @@ defaults: - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results - - test_ubuntu1604_clang: &test_ubuntu1604_clang + # -------------------------------------------------------------------------- + # Base Image Templates + + - base_ubuntu1604_clang: &base_ubuntu1604_clang docker: - image: << pipeline.parameters.ubuntu-1604-clang-ossfuzz-docker-image >> - <<: *steps_soltest - - test_ubuntu2004_clang: &test_ubuntu2004_clang + - base_ubuntu2004_clang: &base_ubuntu2004_clang docker: - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> - <<: *steps_soltest - - test_ubuntu2004: &test_ubuntu2004 + - base_ubuntu2004: &base_ubuntu2004 docker: - image: << pipeline.parameters.ubuntu-2004-docker-image >> - parallelism: 6 - <<: *steps_soltest_all - # -------------------------------------------------------------------------- # Workflow Templates @@ -551,7 +552,8 @@ jobs: - persist_to_workspace: *artifacts_executables t_ubu_codecov: - <<: *test_ubuntu2004 + <<: *base_ubuntu2004 + parallelism: 6 environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 1 @@ -598,7 +600,7 @@ jobs: - persist_to_workspace: *artifacts_executables_ossfuzz t_ubu_ossfuzz: &t_ubu_ossfuzz - <<: *test_ubuntu1604_clang + <<: *base_ubuntu1604_clang steps: - checkout - attach_workspace: @@ -739,7 +741,9 @@ jobs: destination: docs-html t_ubu_soltest: &t_ubu_soltest - <<: *test_ubuntu2004 + <<: *base_ubuntu2004 + parallelism: 6 + <<: *steps_soltest_all t_archlinux_soltest: &t_archlinux_soltest docker: @@ -772,12 +776,15 @@ jobs: t_ubu_clang_soltest: &t_ubu_clang_soltest - <<: *test_ubuntu2004_clang + <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 + <<: *steps_soltest t_ubu_release_soltest: &t_ubu_release_soltest + # NOTE: This definition is identical to t_ubu_soltest_all but in the workflow we make it depend on + # a different job (b_ubu_release) so the workspace it attaches contains a different executable. <<: *t_ubu_soltest t_ubu_cli: &t_ubu_cli @@ -798,20 +805,23 @@ jobs: <<: *steps_cmdline_tests t_ubu_asan: - <<: *test_ubuntu2004 + <<: *base_ubuntu2004 + parallelism: 6 environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 SOLTEST_FLAGS: --no-smt ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 + <<: *steps_soltest t_ubu_asan_clang: - <<: *test_ubuntu2004_clang + <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 SOLTEST_FLAGS: --no-smt ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 + <<: *steps_soltest t_ubu_ubsan_clang: environment: From 9c96234724d40c760c6708c44d8ff5150dd06d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 17:37:05 +0200 Subject: [PATCH 0065/1748] CI: Define a `base_` dict for every image and set default values for some env variables there --- .circleci/config.yml | 267 ++++++++++++++++++++++--------------------- 1 file changed, 135 insertions(+), 132 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 82c860bb7b..97b61107f7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -212,14 +212,93 @@ defaults: - base_ubuntu1604_clang: &base_ubuntu1604_clang docker: - image: << pipeline.parameters.ubuntu-1604-clang-ossfuzz-docker-image >> + environment: + TERM: xterm - base_ubuntu2004_clang: &base_ubuntu2004_clang docker: - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> + environment: + TERM: xterm + CC: clang + CXX: clang++ + MAKEFLAGS: -j 3 + + - base_ubuntu2004_clang_xlarge: &base_ubuntu2004_clang_xlarge + <<: *base_ubuntu2004_clang + resource_class: xlarge + environment: + TERM: xterm + CC: clang + CXX: clang++ + MAKEFLAGS: -j 10 - base_ubuntu2004: &base_ubuntu2004 docker: - image: << pipeline.parameters.ubuntu-2004-docker-image >> + environment: + TERM: xterm + + - base_ubuntu2004_xlarge: &base_ubuntu2004_xlarge + <<: *base_ubuntu2004 + resource_class: xlarge + environment: + TERM: xterm + MAKEFLAGS: -j 10 + + - base_buildpack_focal: &base_buildpack_focal + docker: + - image: buildpack-deps:focal + environment: + TERM: xterm + + - base_buildpack_latest: &base_buildpack_latest + docker: + - image: buildpack-deps:latest + environment: + TERM: xterm + + - base_archlinux: &base_archlinux + docker: + - image: archlinux:base + environment: + TERM: xterm + + - base_win_powershell: &base_win_powershell + executor: + name: win/default + shell: powershell.exe + + - base_win_cmd: &base_win_cmd + executor: + name: win/default + shell: cmd.exe + + - base_osx: &base_osx + macos: + xcode: "11.0.0" + environment: + TERM: xterm + + - base_ems_xlarge: &base_ems_xlarge + docker: + - image: << pipeline.parameters.emscripten-docker-image >> + resource_class: xlarge + environment: + TERM: xterm + MAKEFLAGS: -j 10 + + - base_python: &base_python + docker: + - image: circleci/python:3.6 + environment: + TERM: xterm + + - base_node_latest: &base_node_latest + docker: + - image: circleci/node + environment: + TERM: xterm # -------------------------------------------------------------------------- # Workflow Templates @@ -303,10 +382,7 @@ defaults: jobs: chk_spelling: - docker: - - image: circleci/python:3.6 - environment: - TERM: xterm + <<: *base_python steps: - checkout - attach_workspace: @@ -320,10 +396,7 @@ jobs: command: ~/.local/bin/codespell -S "*.enc,.git,Dockerfile*" -I ./scripts/codespell_whitelist.txt chk_docs_examples: - docker: - - image: circleci/node - environment: - TERM: xterm + <<: *base_node_latest steps: - checkout - attach_workspace: @@ -336,8 +409,7 @@ jobs: command: ./test/docsCodeStyle.sh chk_coding_style: - docker: - - image: buildpack-deps:focal + <<: *base_buildpack_focal steps: - checkout - run: @@ -354,8 +426,7 @@ jobs: command: ./scripts/check_symlinks.sh chk_errorcodes: - docker: - - image: circleci/python:3.6 + <<: *base_python steps: - checkout - run: @@ -363,8 +434,7 @@ jobs: command: ./scripts/error_codes.py --check chk_pylint: - docker: - - image: buildpack-deps:focal + <<: *base_buildpack_focal steps: - checkout - run: @@ -379,8 +449,7 @@ jobs: command: ./scripts/pylint_all.py chk_antlr_grammar: - docker: - - image: buildpack-deps:focal + <<: *base_buildpack_focal steps: - checkout - run: @@ -391,10 +460,7 @@ jobs: command: ./scripts/test_antlr_grammar.sh chk_buglist: - docker: - - image: circleci/node - environment: - TERM: xterm + <<: *base_node_latest steps: - checkout - run: @@ -408,10 +474,7 @@ jobs: command: ./test/buglistTests.js chk_proofs: - docker: - - image: buildpack-deps:latest - environment: - TERM: xterm + <<: *base_buildpack_latest steps: - checkout - run: @@ -423,17 +486,13 @@ jobs: - run: *run_proofs chk_docs_pragma_min_version: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> - environment: - TERM: xterm + <<: *base_ubuntu2004 steps: - checkout - run: *run_docs_pragma_min_version t_pyscripts_ubu: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> + <<: *base_ubuntu2004 steps: - checkout - run: @@ -441,9 +500,7 @@ jobs: command: python3 test/pyscriptTests.py t_pyscripts_win: - executor: - name: win/default - shell: powershell.exe + <<: *base_win_powershell steps: - run: git config --global core.autocrlf false - checkout @@ -452,11 +509,7 @@ jobs: command: python.exe test/pyscriptTests.py b_ubu: &b_ubu - resource_class: xlarge - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> - environment: - MAKEFLAGS: -j 10 + <<: *base_ubuntu2004_xlarge steps: - checkout - run: *run_build @@ -467,7 +520,7 @@ jobs: # x64 ASAN build, for testing for memory related bugs b_ubu_asan: &b_ubu_asan - <<: *b_ubu + <<: *base_ubuntu2004_xlarge environment: CMAKE_OPTIONS: -DSANITIZE=address MAKEFLAGS: -j 10 @@ -479,13 +532,7 @@ jobs: - persist_to_workspace: *artifacts_executables b_ubu_clang: &b_ubu_clang - resource_class: xlarge - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> - environment: - CC: clang - CXX: clang++ - MAKEFLAGS: -j 10 + <<: *base_ubuntu2004_clang_xlarge steps: - checkout - run: *run_build @@ -493,8 +540,7 @@ jobs: - persist_to_workspace: *artifacts_executables b_ubu_asan_clang: &b_ubu_asan_clang - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> + <<: *base_ubuntu2004_clang environment: CC: clang CXX: clang++ @@ -507,8 +553,7 @@ jobs: - persist_to_workspace: *artifacts_executables b_ubu_ubsan_clang: &b_ubu_ubsan_clang - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> + <<: *base_ubuntu2004_clang environment: CC: clang CXX: clang++ @@ -528,7 +573,7 @@ jobs: MAKEFLAGS: -j 10 b_ubu_static: - <<: *b_ubu + <<: *base_ubuntu2004_xlarge environment: MAKEFLAGS: -j 10 CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DUSE_CVC4=OFF -DSOLC_STATIC_STDLIBS=ON @@ -541,7 +586,7 @@ jobs: - store_artifacts: *artifacts_solc b_ubu_codecov: - <<: *b_ubu + <<: *base_ubuntu2004_xlarge environment: COVERAGE: ON CMAKE_BUILD_TYPE: Debug @@ -576,7 +621,7 @@ jobs: # Builds in C++20 mode and uses debug build in order to speed up. # Do *NOT* store any artifacts or workspace as we don't run tests on this build. b_ubu_cxx20: - <<: *b_ubu + <<: *base_ubuntu2004_xlarge environment: CMAKE_BUILD_TYPE: Debug CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 -DUSE_CVC4=OFF @@ -586,13 +631,7 @@ jobs: - run: *run_build b_ubu_ossfuzz: &b_ubu_ossfuzz - docker: - - image: << pipeline.parameters.ubuntu-1604-clang-ossfuzz-docker-image >> - environment: - CC: clang - CXX: clang++ - TERM: xterm - MAKEFLAGS: -j 3 + <<: *base_ubuntu1604_clang steps: - checkout - run: *setup_prerelease_commit_hash @@ -617,8 +656,7 @@ jobs: - store_artifacts: *artifacts_test_results b_archlinux: - docker: - - image: archlinux:base + <<: *base_archlinux environment: TERM: xterm MAKEFLAGS: -j 3 @@ -633,8 +671,7 @@ jobs: - persist_to_workspace: *artifacts_executables b_osx: - macos: - xcode: "11.0.0" + <<: *base_osx environment: TERM: xterm CMAKE_BUILD_TYPE: Release @@ -670,8 +707,7 @@ jobs: - build/test/tools/solfuzzer t_osx_soltest: - macos: - xcode: "11.0.0" + <<: *base_osx environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 @@ -688,10 +724,7 @@ jobs: - store_artifacts: *artifacts_test_results t_osx_cli: - macos: - xcode: "11.0.0" - environment: - TERM: xterm + <<: *base_osx steps: - checkout - restore_cache: @@ -703,12 +736,7 @@ jobs: - store_artifacts: *artifacts_test_results b_ems: - resource_class: xlarge - docker: - - image: << pipeline.parameters.emscripten-docker-image >> - environment: - MAKEFLAGS: -j 10 - TERM: xterm + <<: *base_ems_xlarge steps: - checkout - run: @@ -728,8 +756,7 @@ jobs: - version.txt b_docs: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> + <<: *base_ubuntu2004 steps: - checkout - run: *setup_prerelease_commit_hash @@ -746,27 +773,25 @@ jobs: <<: *steps_soltest_all t_archlinux_soltest: &t_archlinux_soltest - docker: - - image: archlinux:base - environment: - EVM: << pipeline.parameters.evm-version >> - OPTIMIZE: 0 - TERM: xterm - # For Archlinux we do not have prebuilt docker images and we would need to build evmone from source, - # thus we forgo semantics tests to speed things up. - SOLTEST_FLAGS: --no-semantic-tests - steps: - - run: - name: Install runtime dependencies - command: | - pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake z3 cvc4 git openssh tar - - when: - condition: true - <<: *steps_soltest + <<: *base_archlinux + environment: + EVM: << pipeline.parameters.evm-version >> + OPTIMIZE: 0 + TERM: xterm + # For Archlinux we do not have prebuilt docker images and we would need to build evmone from source, + # thus we forgo semantics tests to speed things up. + SOLTEST_FLAGS: --no-semantic-tests + steps: + - run: + name: Install runtime dependencies + command: | + pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake z3 cvc4 git openssh tar + - when: + condition: true + <<: *steps_soltest t_ubu_soltest_enforce_yul: &t_ubu_soltest_enforce_yul - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> + <<: *base_ubuntu2004 environment: EVM: << pipeline.parameters.evm-version >> SOLTEST_FLAGS: --enforce-via-yul @@ -774,7 +799,6 @@ jobs: TERM: xterm <<: *steps_soltest - t_ubu_clang_soltest: &t_ubu_clang_soltest <<: *base_ubuntu2004_clang environment: @@ -788,17 +812,14 @@ jobs: <<: *t_ubu_soltest t_ubu_cli: &t_ubu_cli - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> - environment: - TERM: xterm + <<: *base_ubuntu2004 <<: *steps_cmdline_tests t_ubu_release_cli: &t_ubu_release_cli <<: *t_ubu_cli t_ubu_asan_cli: - <<: *t_ubu_cli + <<: *base_ubuntu2004 environment: TERM: xterm ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 @@ -824,10 +845,9 @@ jobs: <<: *steps_soltest t_ubu_ubsan_clang: + <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> steps: - when: condition: true @@ -835,8 +855,7 @@ jobs: - gitter_notify_failure t_ubu_ubsan_clang_cli: - docker: - - image: << pipeline.parameters.ubuntu-2004-clang-docker-image >> + <<: *base_ubuntu2004_clang steps: - when: condition: true @@ -844,10 +863,7 @@ jobs: - gitter_notify_failure t_ems_solcjs: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> - environment: - TERM: xterm + <<: *base_ubuntu2004 steps: - checkout - attach_workspace: @@ -866,8 +882,7 @@ jobs: test/externalTests/solc-js/solc-js.sh /tmp/workspace/soljson.js $(cat /tmp/workspace/version.txt) t_ems_ext_hardhat: - docker: - - image: circleci/node + <<: *base_node_latest environment: TERM: xterm HARDHAT_TESTS_SOLC_PATH: /tmp/workspace/soljson.js @@ -929,9 +944,7 @@ jobs: - gitter_notify_success b_win: &b_win - executor: - name: win/default - shell: powershell.exe + <<: *base_win_powershell steps: # NOTE: Not disabling git's core.autocrlf here because we want to build using the typical Windows config. - checkout @@ -966,9 +979,7 @@ jobs: FORCE_RELEASE: ON t_win: &t_win - executor: - name: win/default - shell: powershell.exe + <<: *base_win_powershell steps: # NOTE: Git's default core.autocrlf is fine for running soltest. We get additional coverage # for files using CRLF that way. @@ -988,8 +999,7 @@ jobs: <<: *t_win b_bytecode_ubu: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> + <<: *base_ubuntu2004 steps: - checkout - attach_workspace: @@ -1009,10 +1019,7 @@ jobs: - bytecode-report-ubuntu-cli.txt b_bytecode_osx: - macos: - xcode: "11.0.0" - environment: - TERM: xterm + <<: *base_osx steps: - checkout - attach_workspace: @@ -1032,9 +1039,7 @@ jobs: - bytecode-report-osx-cli.txt b_bytecode_win: - executor: - name: win/default - shell: cmd.exe + <<: *base_win_cmd steps: # NOTE: For bytecode generation we need the input files to be byte-for-byte identical on all # platforms so line ending conversions must absolutely be disabled. @@ -1057,8 +1062,7 @@ jobs: - bytecode-report-windows-cli.txt b_bytecode_ems: - docker: - - image: circleci/node:16 + <<: *base_node_latest environment: SOLC_EMSCRIPTEN: "On" steps: @@ -1074,8 +1078,7 @@ jobs: - bytecode-report-emscripten.txt t_bytecode_compare: - docker: - - image: << pipeline.parameters.ubuntu-2004-docker-image >> + <<: *base_ubuntu2004 environment: REPORT_FILES: | bytecode-report-emscripten.txt From c76a8a738dc0274f4623deccf0b2453dbac1b772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 17:56:50 +0200 Subject: [PATCH 0066/1748] CI: Tweak some job names to better reflect what they run --- .circleci/config.yml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 97b61107f7..e2ba6e2d09 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -491,7 +491,7 @@ jobs: - checkout - run: *run_docs_pragma_min_version - t_pyscripts_ubu: + t_ubu_pyscripts: <<: *base_ubuntu2004 steps: - checkout @@ -499,7 +499,7 @@ jobs: name: Python unit tests command: python3 test/pyscriptTests.py - t_pyscripts_win: + t_win_pyscripts: <<: *base_win_powershell steps: - run: git config --global core.autocrlf false @@ -767,7 +767,7 @@ jobs: path: docs/_build/html/ destination: docs-html - t_ubu_soltest: &t_ubu_soltest + t_ubu_soltest_all: &t_ubu_soltest_all <<: *base_ubuntu2004 parallelism: 6 <<: *steps_soltest_all @@ -806,10 +806,10 @@ jobs: OPTIMIZE: 0 <<: *steps_soltest - t_ubu_release_soltest: &t_ubu_release_soltest + t_ubu_release_soltest_all: &t_ubu_release_soltest_all # NOTE: This definition is identical to t_ubu_soltest_all but in the workflow we make it depend on # a different job (b_ubu_release) so the workspace it attaches contains a different executable. - <<: *t_ubu_soltest + <<: *t_ubu_soltest_all t_ubu_cli: &t_ubu_cli <<: *base_ubuntu2004 @@ -825,7 +825,7 @@ jobs: ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 <<: *steps_cmdline_tests - t_ubu_asan: + t_ubu_asan_soltest: <<: *base_ubuntu2004 parallelism: 6 environment: @@ -835,7 +835,7 @@ jobs: ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 <<: *steps_soltest - t_ubu_asan_clang: + t_ubu_asan_clang_soltest: <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> @@ -844,7 +844,7 @@ jobs: ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 <<: *steps_soltest - t_ubu_ubsan_clang: + t_ubu_ubsan_clang_soltest: <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> @@ -978,7 +978,7 @@ jobs: environment: FORCE_RELEASE: ON - t_win: &t_win + t_win_soltest: &t_win_soltest <<: *base_win_powershell steps: # NOTE: Git's default core.autocrlf is fine for running soltest. We get additional coverage @@ -995,8 +995,8 @@ jobs: - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results - t_win_release: - <<: *t_win + t_win_release_soltest: + <<: *t_win_soltest b_bytecode_ubu: <<: *base_ubuntu2004 @@ -1128,8 +1128,8 @@ workflows: - chk_errorcodes: *workflow_trigger_on_tags - chk_antlr_grammar: *workflow_trigger_on_tags - chk_docs_pragma_min_version: *workflow_trigger_on_tags - - t_pyscripts_ubu: *workflow_trigger_on_tags - - t_pyscripts_win: *workflow_trigger_on_tags + - t_ubu_pyscripts: *workflow_trigger_on_tags + - t_win_pyscripts: *workflow_trigger_on_tags # build-only - b_docs: *workflow_trigger_on_tags @@ -1151,7 +1151,7 @@ workflows: # Ubuntu build and tests - b_ubu: *workflow_trigger_on_tags - t_ubu_cli: *workflow_ubuntu2004 - - t_ubu_soltest: *workflow_ubuntu2004 + - t_ubu_soltest_all: *workflow_ubuntu2004 - t_ubu_soltest_enforce_yul: *workflow_ubuntu2004 - b_ubu_clang: *workflow_trigger_on_tags - t_ubu_clang_soltest: *workflow_ubuntu2004_clang @@ -1159,7 +1159,7 @@ workflows: # Ubuntu fake release build and tests - b_ubu_release: *workflow_trigger_on_tags - t_ubu_release_cli: *workflow_ubuntu2004_release - - t_ubu_release_soltest: *workflow_ubuntu2004_release + - t_ubu_release_soltest_all: *workflow_ubuntu2004_release # Emscripten build and tests that take 15 minutes or less - b_ems: *workflow_trigger_on_tags @@ -1222,8 +1222,8 @@ workflows: # Windows build and tests - b_win: *workflow_trigger_on_tags - b_win_release: *workflow_trigger_on_tags - - t_win: *workflow_win - - t_win_release: *workflow_win_release + - t_win_soltest: *workflow_win + - t_win_release_soltest: *workflow_win_release # Bytecode comparison: - b_bytecode_ubu: @@ -1267,13 +1267,13 @@ workflows: # ASan build and tests - b_ubu_asan: *workflow_trigger_on_tags - b_ubu_asan_clang: *workflow_trigger_on_tags - - t_ubu_asan: *workflow_ubuntu2004_asan - - t_ubu_asan_clang: *workflow_ubuntu2004_asan_clang + - t_ubu_asan_soltest: *workflow_ubuntu2004_asan + - t_ubu_asan_clang_soltest: *workflow_ubuntu2004_asan_clang - t_ubu_asan_cli: *workflow_ubuntu2004_asan # UBSan build and tests - b_ubu_ubsan_clang: *workflow_trigger_on_tags - - t_ubu_ubsan_clang: *workflow_ubuntu2004_ubsan_clang + - t_ubu_ubsan_clang_soltest: *workflow_ubuntu2004_ubsan_clang - t_ubu_ubsan_clang_cli: *workflow_ubuntu2004_ubsan_clang # Emscripten build and tests that take more than 15 minutes to execute From dff280cadc6ec83e39e1bdabc2673d56ab528f95 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 3 Nov 2021 15:40:54 +0100 Subject: [PATCH 0067/1748] Fix ICE in CHC when using gas in the function options --- Changelog.md | 1 + libsolidity/formal/CHC.cpp | 4 ++-- .../external_calls/external_call_with_gas_1.sol | 9 +++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/external_calls/external_call_with_gas_1.sol diff --git a/Changelog.md b/Changelog.md index c724693eeb..e17420b679 100644 --- a/Changelog.md +++ b/Changelog.md @@ -23,6 +23,7 @@ Bugfixes: * Commandline Interface: Report output selection options unsupported by the selected input mode instead of ignoring them. * Commandline Interface: When linking only accept exact matches for library names passed to the ``--libraries`` option. Library names not prefixed with a file name used to match any library with that name. * SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``). + * SMTChecker: Fix internal error in the CHC engine when passing gas in the function options. * TypeChecker: Fix internal error when using user defined value types in public library functions. * TypeChecker: Fix internal error when using arrays and structs with user defined value types before declaration. * TypeChecker: Improved error message for constant variables with (nested) mapping types. diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index c0a92264e6..76a5ded998 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -791,8 +791,8 @@ void CHC::externalFunctionCall(FunctionCall const& _funCall) valueIndex = i; break; } - solAssert(valueIndex, ""); - state().addBalance(state().thisAddress(), 0 - expr(*callOptions->options().at(*valueIndex))); + if (valueIndex) + state().addBalance(state().thisAddress(), 0 - expr(*callOptions->options().at(*valueIndex))); } auto preCallState = vector{state().state()} + currentStateVariables(); diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_with_gas_1.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_with_gas_1.sol new file mode 100644 index 0000000000..86cbbe9b5a --- /dev/null +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_with_gas_1.sol @@ -0,0 +1,9 @@ +library L { + function f() public view { + (bool success, ) = address(10).staticcall{gas: 3}(""); + require(success); + } +} +// ==== +// SMTEngine: all +// ---- From 45b87d41f7aabcde14ec87b96ccef61bf6622f4d Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 3 Nov 2021 16:38:36 +0100 Subject: [PATCH 0068/1748] Add missing changelog entry. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index c724693eeb..f92e20c7e6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Compiler Features: * SMTChecker: Report contract invariants and reentrancy properties. This can be enabled via the CLI option ``--model-checker-invariants`` or the Standard JSON option ``settings.modelChecker.invariants``. * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. * Standard JSON: Add ``settings.debug.debugInfo`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. + * Yul EVM Code Transform: Switch to new optimized code transform when compiling via Yul with enabled optimizer. * Yul Optimizer: Take control-flow side-effects of user-defined functions into account in various optimizer steps. From 0cbb297c7bf7a81b54ec7c429e65367a78e901d6 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 2 Nov 2021 11:07:52 +0100 Subject: [PATCH 0069/1748] Non-interactive mode for yulopti. --- test/tools/yulopti.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 752aaafa6c..da5ae4871e 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -162,6 +162,36 @@ class YulOpti } } + int runSteps(string source, string steps) + { + if (!parse(source)) + return 1; + + set reservedIdentifiers; + *m_ast = std::get(Disambiguator(m_dialect, *m_analysisInfo)(*m_ast)); + m_analysisInfo.reset(); + m_nameDispenser = make_shared(m_dialect, *m_ast, reservedIdentifiers); + + OptimiserStepContext context{ + m_dialect, + *m_nameDispenser, + reservedIdentifiers, + solidity::frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment + }; + + map const& abbreviationMap = OptimiserSuite::stepAbbreviationToNameMap(); + for (char stepAbbreviation: steps) + if (auto abbreviationAndName = util::valueOrNullptr(abbreviationMap, stepAbbreviation)) + OptimiserSuite::allSteps().at(*abbreviationAndName)->run(context, *m_ast); + else + { + cerr << "Unknown optimizer step." << endl; + return 1; + } + cout << AsmPrinter{m_dialect}(*m_ast) << endl; + return 0; + } + void runInteractive(string source) { bool disambiguated = false; @@ -256,6 +286,11 @@ Allowed options)", po::value(), "input file" ) + ( + "steps", + po::value(), + "steps to execute non-interactively" + ) ("help", "Show this help screen."); // All positional options should be interpreted as input files @@ -292,7 +327,12 @@ Allowed options)", } if (arguments.count("input-file")) - YulOpti{}.runInteractive(input); + { + if (arguments.count("steps")) + return YulOpti{}.runSteps(input, arguments["steps"].as()); + else + YulOpti{}.runInteractive(input); + } else cout << options; From 95c973d6c2b12d39f1014d45f686c80d6aafb786 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 3 Nov 2021 12:12:37 +0100 Subject: [PATCH 0070/1748] Refactoring of optimiser suite and yulopti. --- libyul/optimiser/Suite.cpp | 7 +- libyul/optimiser/Suite.h | 17 +- test/tools/yulopti.cpp | 319 ++++++++++++++++++++----------------- 3 files changed, 183 insertions(+), 160 deletions(-) diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index bd81f7c0b4..32ea08dbe1 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -111,7 +111,10 @@ void OptimiserSuite::run( )(*_object.code)); Block& ast = *_object.code; - OptimiserSuite suite(_dialect, reservedIdentifiers, Debug::None, ast, _expectedExecutionsPerDeployment); + NameDispenser dispenser{_dialect, ast, reservedIdentifiers}; + OptimiserStepContext context{_dialect, dispenser, reservedIdentifiers, _expectedExecutionsPerDeployment}; + + OptimiserSuite suite(context, Debug::None); // Some steps depend on properties ensured by FunctionHoister, BlockFlattener, FunctionGrouper and // ForLoopInitRewriter. Run them first to be able to run arbitrary sequences safely. @@ -162,7 +165,7 @@ void OptimiserSuite::run( ast.statements.erase(ast.statements.begin()); } - suite.m_dispenser.reset(ast); + dispenser.reset(ast); NameSimplifier::run(suite.m_context, ast); VarNameCleaner::run(suite.m_context, ast); diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h index 9b38ce542f..3c85fc559a 100644 --- a/libyul/optimiser/Suite.h +++ b/libyul/optimiser/Suite.h @@ -59,6 +59,8 @@ class OptimiserSuite PrintStep, PrintChanges }; + OptimiserSuite(OptimiserStepContext& _context, Debug _debug = Debug::None): m_context(_context), m_debug(_debug) {} + /// The value nullopt for `_expectedExecutionsPerDeployment` represents creation code. static void run( Dialect const& _dialect, @@ -82,20 +84,7 @@ class OptimiserSuite static std::map const& stepAbbreviationToNameMap(); private: - OptimiserSuite( - Dialect const& _dialect, - std::set const& _externallyUsedIdentifiers, - Debug _debug, - Block& _ast, - std::optional expectedExecutionsPerDeployment - ): - m_dispenser{_dialect, _ast, _externallyUsedIdentifiers}, - m_context{_dialect, m_dispenser, _externallyUsedIdentifiers, expectedExecutionsPerDeployment}, - m_debug(_debug) - {} - - NameDispenser m_dispenser; - OptimiserStepContext m_context; + OptimiserStepContext& m_context; Debug m_debug; }; diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index da5ae4871e..5c4f00f0a9 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -76,58 +76,66 @@ namespace po = boost::program_options; class YulOpti { public: - void printErrors() + static void printErrors(CharStream const& _charStream, ErrorList const& _errors) { SourceReferenceFormatter{ cerr, - SingletonCharStreamProvider(*m_charStream), + SingletonCharStreamProvider(_charStream), true, false - }.printErrorInformation(m_errors); + }.printErrorInformation(_errors); } - bool parse(string const& _input) + void parse(string const& _input) { - ErrorReporter errorReporter(m_errors); - m_charStream = make_shared(_input, ""); - m_ast = yul::Parser(errorReporter, m_dialect).parse(*m_charStream); - if (!m_ast || !errorReporter.errors().empty()) + ErrorList errors; + ErrorReporter errorReporter(errors); + CharStream _charStream(_input, ""); + try { - cerr << "Error parsing source." << endl; - printErrors(); - return false; + m_ast = yul::Parser(errorReporter, m_dialect).parse(_charStream); + if (!m_ast || !errorReporter.errors().empty()) + { + cerr << "Error parsing source." << endl; + printErrors(_charStream, errors); + throw std::runtime_error("Could not parse source."); + } + m_analysisInfo = make_unique(); + AsmAnalyzer analyzer( + *m_analysisInfo, + errorReporter, + m_dialect + ); + if (!analyzer.analyze(*m_ast) || !errorReporter.errors().empty()) + { + cerr << "Error analyzing source." << endl; + printErrors(_charStream, errors); + throw std::runtime_error("Could not analyze source."); + } } - m_analysisInfo = make_shared(); - AsmAnalyzer analyzer( - *m_analysisInfo, - errorReporter, - m_dialect - ); - if (!analyzer.analyze(*m_ast) || !errorReporter.errors().empty()) + catch(...) { - cerr << "Error analyzing source." << endl; - printErrors(); - return false; + cerr << "Fatal error during parsing: " << endl; + printErrors(_charStream, errors); + throw; } - return true; } void printUsageBanner( - map const& _optimizationSteps, map const& _extraOptions, size_t _columns ) { yulAssert(_columns > 0); - + auto const& optimiserSteps = OptimiserSuite::stepAbbreviationToNameMap(); auto hasShorterString = [](auto const& a, auto const& b) { return a.second.size() < b.second.size(); }; size_t longestDescriptionLength = std::max( - max_element(_optimizationSteps.begin(), _optimizationSteps.end(), hasShorterString)->second.size(), + max_element(optimiserSteps.begin(), optimiserSteps.end(), hasShorterString)->second.size(), max_element(_extraOptions.begin(), _extraOptions.end(), hasShorterString)->second.size() ); vector overlappingAbbreviations = - ranges::views::set_intersection(_extraOptions | ranges::views::keys, _optimizationSteps | ranges::views::keys) | + ranges::views::set_intersection(_extraOptions | ranges::views::keys, optimiserSteps | ranges::views::keys) | ranges::views::transform([](char _abbreviation){ return string(1, _abbreviation); }) | ranges::to(); @@ -141,7 +149,7 @@ class YulOpti ); vector> sortedOptions = - ranges::views::concat(_optimizationSteps, _extraOptions) | + ranges::views::concat(optimiserSteps, _extraOptions) | ranges::to>>() | ranges::actions::sort([](tuple const& _a, tuple const& _b) { return ( @@ -162,54 +170,28 @@ class YulOpti } } - int runSteps(string source, string steps) + void disambiguate() { - if (!parse(source)) - return 1; - - set reservedIdentifiers; *m_ast = std::get(Disambiguator(m_dialect, *m_analysisInfo)(*m_ast)); m_analysisInfo.reset(); - m_nameDispenser = make_shared(m_dialect, *m_ast, reservedIdentifiers); - - OptimiserStepContext context{ - m_dialect, - *m_nameDispenser, - reservedIdentifiers, - solidity::frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment - }; - - map const& abbreviationMap = OptimiserSuite::stepAbbreviationToNameMap(); - for (char stepAbbreviation: steps) - if (auto abbreviationAndName = util::valueOrNullptr(abbreviationMap, stepAbbreviation)) - OptimiserSuite::allSteps().at(*abbreviationAndName)->run(context, *m_ast); - else - { - cerr << "Unknown optimizer step." << endl; - return 1; - } + m_nameDispenser.reset(*m_ast); + } + + void runSteps(string _source, string _steps) + { + parse(_source); + disambiguate(); + OptimiserSuite{m_context}.runSequence(_steps, *m_ast); cout << AsmPrinter{m_dialect}(*m_ast) << endl; - return 0; } - void runInteractive(string source) + void runInteractive(string _source, bool _disambiguated = false) { - bool disambiguated = false; + bool disambiguated = _disambiguated; while (true) { - cout << "----------------------" << endl; - cout << source << endl; - if (!parse(source)) - return; - set reservedIdentifiers; - if (!disambiguated) - { - *m_ast = std::get(Disambiguator(m_dialect, *m_analysisInfo)(*m_ast)); - m_analysisInfo.reset(); - m_nameDispenser = make_shared(m_dialect, *m_ast, reservedIdentifiers); - disambiguated = true; - } - map const& abbreviationMap = OptimiserSuite::stepAbbreviationToNameMap(); + parse(_source); + disambiguated = disambiguated || (disambiguate(), true); map const& extraOptions = { // QUIT starts with a non-letter character on purpose to get it to show up on top of the list {'#', ">>> QUIT <<<"}, @@ -217,104 +199,159 @@ class YulOpti {';', "StackCompressor"} }; - printUsageBanner(abbreviationMap, extraOptions, 4); + printUsageBanner(extraOptions, 4); cout << "? "; cout.flush(); - // TODO: handle EOF properly. char option = static_cast(readStandardInputChar()); cout << ' ' << option << endl; - OptimiserStepContext context{ - m_dialect, - *m_nameDispenser, - reservedIdentifiers, - solidity::frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment - }; - - auto abbreviationAndName = abbreviationMap.find(option); - if (abbreviationAndName != abbreviationMap.end()) + try { - OptimiserStep const& step = *OptimiserSuite::allSteps().at(abbreviationAndName->second); - step.run(context, *m_ast); + switch (option) + { + case 4: + case '#': + return; + case ',': + VarNameCleaner::run(m_context, *m_ast); + // VarNameCleaner destroys the unique names guarantee of the disambiguator. + disambiguated = false; + break; + case ';': + { + Object obj; + obj.code = m_ast; + StackCompressor::run(m_dialect, obj, true, 16); + break; + } + default: + OptimiserSuite{m_context}.runSequence( + std::string_view(&option, 1), + *m_ast + ); + } + _source = AsmPrinter{m_dialect}(*m_ast); } - else switch (option) - { - case '#': - return; - case ',': - VarNameCleaner::run(context, *m_ast); - // VarNameCleaner destroys the unique names guarantee of the disambiguator. - disambiguated = false; - break; - case ';': + catch (...) { - Object obj; - obj.code = m_ast; - StackCompressor::run(m_dialect, obj, true, 16); - break; + cerr << endl << "Exception during optimiser step:" << endl; + cerr << boost::current_exception_diagnostic_information() << endl; } - default: - cerr << "Unknown option." << endl; - } - source = AsmPrinter{m_dialect}(*m_ast); + cout << "----------------------" << endl; + cout << _source << endl; } } private: - ErrorList m_errors; - shared_ptr m_charStream; shared_ptr m_ast; Dialect const& m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion{})}; - shared_ptr m_analysisInfo; - shared_ptr m_nameDispenser; + unique_ptr m_analysisInfo; + set const m_reservedIdentifiers = {}; + NameDispenser m_nameDispenser{m_dialect, m_reservedIdentifiers}; + OptimiserStepContext m_context{ + m_dialect, + m_nameDispenser, + m_reservedIdentifiers, + solidity::frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment + }; }; int main(int argc, char** argv) { - po::options_description options( - R"(yulopti, yul optimizer exploration tool. -Usage: yulopti [Options] -Reads as yul code and applies optimizer steps to it, -interactively read from stdin. - -Allowed options)", - po::options_description::m_default_line_length, - po::options_description::m_default_line_length - 23); - options.add_options() - ( - "input-file", - po::value(), - "input file" - ) - ( - "steps", - po::value(), - "steps to execute non-interactively" - ) - ("help", "Show this help screen."); - - // All positional options should be interpreted as input files - po::positional_options_description filesPositions; - filesPositions.add("input-file", 1); - - po::variables_map arguments; try { + bool nonInteractive = false; + po::options_description options( + R"(yulopti, yul optimizer exploration tool. + Usage: yulopti [Options] + Reads as yul code and applies optimizer steps to it, + interactively read from stdin. + In non-interactive mode a list of steps has to be provided. + If is -, yul code is read from stdin and run non-interactively. + + Allowed options)", + po::options_description::m_default_line_length, + po::options_description::m_default_line_length - 23); + options.add_options() + ( + "input-file", + po::value(), + "input file" + ) + ( + "steps", + po::value(), + "steps to execute non-interactively" + ) + ( + "non-interactive,n", + po::bool_switch(&nonInteractive)->default_value(false), + "stop after executing the provided steps" + ) + ("help,h", "Show this help screen."); + + // All positional options should be interpreted as input files + po::positional_options_description filesPositions; + filesPositions.add("input-file", 1); + + po::variables_map arguments; po::command_line_parser cmdLineParser(argc, argv); cmdLineParser.options(options).positional(filesPositions); po::store(cmdLineParser.run(), arguments); + po::notify(arguments); + + if (arguments.count("help")) + { + cout << options; + return 0; + } + + string input; + if (arguments.count("input-file")) + { + string filename = arguments["input-file"].as(); + if (filename == "-") + { + nonInteractive = true; + input = readUntilEnd(cin); + } + else + input = readFileAsString(arguments["input-file"].as()); + } + else + { + cout << options; + return 1; + } + + if (nonInteractive && !arguments.count("steps")) + { + cout << options; + return 1; + } + + YulOpti yulOpti; + bool disambiguated = false; + if (!nonInteractive) + cout << input << endl; + if (arguments.count("steps")) + { + string sequence = arguments["steps"].as(); + if (!nonInteractive) + cout << "----------------------" << endl; + yulOpti.runSteps(input, sequence); + disambiguated = true; + } + if (!nonInteractive) + yulOpti.runInteractive(input, disambiguated); + + return 0; } catch (po::error const& _exception) { cerr << _exception.what() << endl; return 1; } - - string input; - try - { - input = readFileAsString(arguments["input-file"].as()); - } catch (FileNotFound const& _exception) { cerr << "File not found:" << _exception.comment() << endl; @@ -325,16 +362,10 @@ Allowed options)", cerr << "Not a regular file:" << _exception.comment() << endl; return 1; } - - if (arguments.count("input-file")) + catch(...) { - if (arguments.count("steps")) - return YulOpti{}.runSteps(input, arguments["steps"].as()); - else - YulOpti{}.runInteractive(input); + cerr << endl << "Exception:" << endl; + cerr << boost::current_exception_diagnostic_information() << endl; + return 1; } - else - cout << options; - - return 0; } From b4a527039faa4517ab94a5fdb49be67b330c002d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20L=C3=B3pez?= Date: Wed, 3 Nov 2021 20:21:31 -0300 Subject: [PATCH 0071/1748] fixed example address payable --- docs/types/value-types.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index c02eea8a9e..f849f3f7eb 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -241,7 +241,7 @@ and to send Ether (in units of wei) to a payable address using the ``transfer`` .. code-block:: solidity :force: - address payable x = address(0x123); + address payable x = payable(0x123); address myAddress = address(this); if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10); From 8e87c176715ae559cb3dc135a411936638fb762a Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Nov 2021 11:44:31 +0100 Subject: [PATCH 0072/1748] Remove old compatibility patch to soljson.js. --- Changelog.md | 4 ++++ scripts/ci/build_emscripten.sh | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index f92e20c7e6..b02bb80c30 100644 --- a/Changelog.md +++ b/Changelog.md @@ -31,6 +31,10 @@ Bugfixes: * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts. +Build System: + * Remove obsolete compatibility workaround for emscripten builds. + + Important Bugfixes in Experimental Features: * Yul IR Generator: Changes to function return variables referenced in modifier invocation arguments were not properly forwarded if there was more than one return variable. diff --git a/scripts/ci/build_emscripten.sh b/scripts/ci/build_emscripten.sh index f4b8d734df..7eac2486f8 100755 --- a/scripts/ci/build_emscripten.sh +++ b/scripts/ci/build_emscripten.sh @@ -68,10 +68,6 @@ emcmake cmake \ -DTESTS=0 \ .. make soljson -# Patch soljson.js for backwards compatibility. -# TODO: remove this with 0.7. -# "viiiii" encodes the signature of the callback function. -sed -i -e 's/addFunction(func,sig){/addFunction(func,sig){sig=sig||"viiiii";/' libsolc/soljson.js cd .. mkdir -p upload From a0dee79ad2ec1b0e943e0a2180984e1443cc5661 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Nov 2021 11:53:45 +0100 Subject: [PATCH 0073/1748] Remove install_deps script. --- docs/installing-solidity.rst | 15 +- scripts/Dockerfile | 3 +- scripts/install_deps.sh | 400 ----------------------------------- 3 files changed, 3 insertions(+), 415 deletions(-) delete mode 100755 scripts/install_deps.sh diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index ea415f0219..dbfa7a4c58 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -411,24 +411,13 @@ in Visual Studio 2019 Build Tools or Visual Studio 2019: .. _Visual Studio 2019: https://www.visualstudio.com/vs/ .. _Visual Studio 2019 Build Tools: https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2019 -Dependencies Helper Script --------------------------- - -We have a helper script which you can use to install all required external dependencies -on macOS, Windows and on numerous Linux distros. - -.. code-block:: bash - - ./scripts/install_deps.sh - -Or, on Windows: +We have a helper script which you can use to install all required external dependencies: .. code-block:: bat scripts\install_deps.ps1 -Note that the latter command will install ``boost`` and ``cmake`` to the ``deps`` subdirectory, while the former command -will attempt to install the dependencies globally. +This will install ``boost`` and ``cmake`` to the ``deps`` subdirectory. Clone the Repository -------------------- diff --git a/scripts/Dockerfile b/scripts/Dockerfile index 2b2de1e27d..3a1c6a5a7c 100644 --- a/scripts/Dockerfile +++ b/scripts/Dockerfile @@ -6,8 +6,7 @@ MAINTAINER chriseth WORKDIR /solidity # Build dependencies -ADD /scripts/install_deps.sh /solidity/scripts/install_deps.sh -RUN ./scripts/install_deps.sh +RUN apk update && apk add boost-dev boost-static build-base cmake git #Copy working directory on travis to the image COPY / $WORKDIR diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh deleted file mode 100755 index 7540c8bdf9..0000000000 --- a/scripts/install_deps.sh +++ /dev/null @@ -1,400 +0,0 @@ -#!/usr/bin/env sh - -#------------------------------------------------------------------------------ -# Shell script for installing pre-requisite packages for solidity on a -# variety of Linux and other UNIX-derived platforms. -# -# This is an "infrastucture-as-code" alternative to the manual build -# instructions pages which we previously maintained at: -# https://docs.soliditylang.org/en/latest/installing-solidity.html -# -# The aim of this script is to simplify things down to the following basic -# flow for all supported operating systems: -# -# - git clone --recursive -# - ./scripts/install_deps.sh -# - cmake && make -# -# TODO - There is no support here yet for cross-builds in any form, only -# native builds. Expanding the functionality here to cover the mobile, -# wearable and SBC platforms covered by doublethink and EthEmbedded would -# also bring in support for Android, iOS, watchOS, tvOS, Tizen, Sailfish, -# Maemo, MeeGo and Yocto. -# -# The documentation for solidity is hosted at: -# -# https://docs.soliditylang.org -# -# ------------------------------------------------------------------------------ -# This file is part of solidity. -# -# solidity is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# solidity is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with solidity. If not, see -# -# (c) 2016 solidity contributors. -#------------------------------------------------------------------------------ - -set -e - -# Check for 'uname' and abort if it is not available. -uname -v > /dev/null 2>&1 || { echo >&2 "ERROR - solidity requires 'uname' to identify the platform."; exit 1; } - -# See http://unix.stackexchange.com/questions/92199/how-can-i-reliably-get-the-operating-systems-name -detect_linux_distro() { - if [ "$(command -v lsb_release)" ]; then - DISTRO=$(lsb_release -is) - elif [ -f /etc/os-release ]; then - # extract 'foo' from NAME=foo, only on the line with NAME=foo - DISTRO=$(sed -n -e 's/^NAME="\?\([^"]*\)"\?$/\1/p' /etc/os-release) - elif [ -f /etc/centos-release ]; then - DISTRO=CentOS - else - DISTRO='' - fi - echo "$DISTRO" -} - -case $(uname -s) in - -#------------------------------------------------------------------------------ -# macOS -#------------------------------------------------------------------------------ - - Darwin) - case $(sw_vers -productVersion | awk -F . '{print $1"."$2}') in - 10.9) - echo "Installing solidity dependencies on OS X 10.9 Mavericks." - ;; - 10.10) - echo "Installing solidity dependencies on OS X 10.10 Yosemite." - ;; - 10.11) - echo "Installing solidity dependencies on OS X 10.11 El Capitan." - ;; - 10.12) - echo "Installing solidity dependencies on macOS 10.12 Sierra." - ;; - 10.13) - echo "Installing solidity dependencies on macOS 10.13 High Sierra." - ;; - 10.14) - echo "Installing solidity dependencies on macOS 10.14 Mojave." - ;; - 10.15) - echo "Installing solidity dependencies on macOS 10.15 Catalina." - ;; - 11.0 | 11.1 | 11.2 | 11.3 | 11.4 | 11.5 | 11.6) - echo "Installing solidity dependencies on macOS 11.0 / 11.1 / 11.2 / 11.3 / 11.4 / 11.5 / 11.6 Big Sur." - ;; - *) - echo "Unsupported macOS version." - echo "We only support Mavericks, Yosemite, El Capitan, Sierra, High Sierra, Mojave, Catalina, and Big Sur." - exit 1 - ;; - esac - - # Check for Homebrew install and abort if it is not installed. - brew -v > /dev/null 2>&1 || { echo >&2 "ERROR - solidity requires a Homebrew install. See https://brew.sh."; exit 1; } - brew update - brew install boost - brew install cmake - if [ "$CI" = true ]; then - brew upgrade cmake - else - brew upgrade - fi - - ;; - -#------------------------------------------------------------------------------ -# FreeBSD -#------------------------------------------------------------------------------ - - FreeBSD) - echo "Installing solidity dependencies on FreeBSD." - echo "ERROR - 'install_deps.sh' doesn't have FreeBSD support yet." - echo "Please let us know if you see this error message, and we can work out what is missing." - echo "Drop us a message at https://gitter.im/ethereum/solidity-dev." - exit 1 - ;; - -#------------------------------------------------------------------------------ -# Linux -#------------------------------------------------------------------------------ - - Linux) - case $(detect_linux_distro) in - -#------------------------------------------------------------------------------ -# Arch Linux -#------------------------------------------------------------------------------ - - Arch*|ManjaroLinux) - #Arch - echo "Installing solidity dependencies on Arch Linux." - - # All our dependencies can be found in the Arch Linux official repositories. - # See https://wiki.archlinux.org/index.php/Official_repositories - sudo pacman -Syu \ - base-devel \ - boost \ - cmake \ - git \ - cvc4 - ;; - -#------------------------------------------------------------------------------ -# Alpine Linux -#------------------------------------------------------------------------------ - - "Alpine Linux") - #Alpine - echo "Installing solidity dependencies on Alpine Linux." - - # All our dependencies can be found in the Alpine Linux official repositories. - # See https://pkgs.alpinelinux.org/ - - apk update - apk add boost-dev boost-static build-base cmake git - - ;; - -#------------------------------------------------------------------------------ -# Debian -#------------------------------------------------------------------------------ - - Debian*|Raspbian) - #Debian - # shellcheck disable=SC1091 - . /etc/os-release - install_z3="" - case $VERSION_ID in - 8) - #jessie - echo "Installing solidity dependencies on Debian Jesse (8.x)." - ;; - 9) - #stretch - echo "Installing solidity dependencies on Debian Stretch (9.x)." - install_z3="libz3-dev" - ;; - 10) - #buster - echo "Installing solidity dependencies on Debian Buster (10.x)." - install_z3="libz3-dev" - ;; - *) - #other Debian - echo "Installing solidity dependencies on unknown Debian version." - echo "ERROR - This might not work, but we are trying anyway." - echo "Drop us a message at https://gitter.im/ethereum/solidity-dev" - install_z3="libz3-dev" - ;; - esac - - # Install "normal packages" - sudo apt-get -y update - sudo apt-get -y install \ - build-essential \ - cmake \ - g++ \ - gcc \ - git \ - libboost-all-dev \ - unzip \ - "$install_z3" - - - ;; - -#------------------------------------------------------------------------------ -# Fedora -#------------------------------------------------------------------------------ - - Fedora) - #Fedora - echo "Installing solidity dependencies on Fedora." - - # Install "normal packages" - # See https://fedoraproject.org/wiki/Package_management_system. - dnf install \ - autoconf \ - automake \ - boost-devel \ - boost-static \ - cmake \ - gcc \ - gcc-c++ \ - git \ - libtool - - ;; - -#------------------------------------------------------------------------------ -# OpenSUSE -#------------------------------------------------------------------------------ - - "openSUSE project") - #openSUSE - echo "Installing solidity dependencies on openSUSE." - echo "ERROR - 'install_deps.sh' doesn't have openSUSE support yet." - echo "See https://docs.soliditylang.org/en/latest/installing-solidity.html for manual instructions." - echo "If you would like to get 'install_deps.sh' working for openSUSE, that would be fantastic." - echo "See https://github.com/ethereum/webthree-umbrella/issues/552." - exit 1 - ;; -#------------------------------------------------------------------------------ -# Ubuntu -# -#------------------------------------------------------------------------------ - - Ubuntu|LinuxMint|Pop) - #LinuxMint is a distro on top of Ubuntu. - #Ubuntu - install_z3="" - case $(lsb_release -cs) in - trusty|qiana|rebecca|rafaela|rosa) - echo "Installing solidity dependencies on Ubuntu Trusty Tahr (14.04)." - echo "Or, you may also be running Linux Mint Qiana / Rebecca / Rafaela / Rosa (base: Ubuntu Trusty Tahr (14.04).)" - ;; - xenial|sarah|serena|sonya|sylvia) - echo "Installing solidity dependencies on Ubuntu Xenial Xerus (16.04)." - echo "Or, you may also be running Linux Mint Sarah / Serena / Sonya / Sylvia (base: Ubuntu Xenial Xerus (16.04).)" - install_z3="libz3-dev" - ;; - bionic) - echo "Installing solidity dependencies." - install_z3="libz3-dev" - ;; - focal) - echo "Installing solidity dependencies." - install_z3="libz3-dev" - ;; - hirsute) - echo "Installing solidity dependencies." - install_z3="libz3-dev" - ;; - betsy) - #do not try anything for betsy. - echo "Linux Mint Betsy is not supported at the moment as it runs off of Debian." - echo "We only support Sylvia, Sonya, Serena, Sarah, Rosa, Rafaela, Rebecca, and Qiana." - echo "See https://docs.soliditylang.org/en/latest/installing-solidity.html for manual instructions." - echo "If you would like to get your distro working, that would be fantastic." - echo "Drop us a message at https://gitter.im/ethereum/solidity-dev." - exit 1 - ;; - *) - #other Ubuntu - echo "ERROR - Unknown or unsupported Ubuntu version ($(lsb_release -cs))" - echo "ERROR - This might not work, but we are trying anyway." - echo "Please drop us a message at https://gitter.im/ethereum/solidity-dev." - echo "We only support Trusty, Xenial, Bionic, Focal, and Hirsute." - install_z3="libz3-dev" - ;; - esac - - sudo apt-get -y update - sudo apt-get -y install \ - build-essential \ - cmake \ - git \ - libboost-all-dev \ - "$install_z3" - if [ "$CI" = true ]; then - # install Z3 from PPA if the distribution does not provide it - if ! dpkg -l libz3-dev > /dev/null 2>&1 - then - sudo apt-add-repository -y ppa:hvr/z3 - sudo apt-get -y update - sudo apt-get -y install libz3-dev - fi - fi - ;; - -#------------------------------------------------------------------------------ -# CentOS -# CentOS needs some more testing. This is the general idea of packages -# needed, but some tweaking/improvements can definitely happen -#------------------------------------------------------------------------------ - CentOS*) - echo "Attention: CentOS 7 is currently not supported!"; - # FIXME: read -p and [[ ]] are bash features but our shebang says we're using sh - # shellcheck disable=SC2039 - read -p "This script will heavily modify your system in order to allow for compilation of Solidity. Are you sure? [Y/N]" -n 1 -r - # shellcheck disable=SC2039 - if [[ $REPLY =~ ^[Yy]$ ]]; then - # Make Sure we have the EPEL repos - sudo yum -y install epel-release - # Get g++ 4.8 - sudo rpm --import http://linuxsoft.cern.ch/cern/slc6X/i386/RPM-GPG-KEY-cern - wget -O /etc/yum.repos.d/slc6-devtoolset.repo http://linuxsoft.cern.ch/cern/devtoolset/slc6-devtoolset.repo - sudo yum -y install devtoolset-2-gcc devtoolset-2-gcc-c++ devtoolset-2-binutils - - # Enable the devtoolset2 usage so global gcc/g++ become the 4.8 one. - # As per https://gist.github.com/stephenturner/e3bc5cfacc2dc67eca8b, what you should do afterwards is - # to add this line: - # source /opt/rh/devtoolset-2/enable - # to your bashrc so that this happens automatically at login - scl enable devtoolset-2 bash - - # Get cmake - sudo yum -y remove cmake - sudo yum -y install cmake3 - sudo ln -s /usr/bin/cmake3 /usr/bin/cmake - - # Get latest boost thanks to this guy: http://vicendominguez.blogspot.de/2014/04/boost-c-library-rpm-packages-for-centos.html - sudo yum -y remove boost-devel - sudo wget https://bintray.com/vicendominguez/CentOS6/rpm -O /etc/yum.repos.d/bintray-vicendominguez-CentOS6.repo - sudo yum install boost-devel - else - echo "Aborted CentOS Solidity Dependency Installation"; - exit 1 - fi - - ;; - - - - - *) - -#------------------------------------------------------------------------------ -# Other (unknown) Linux -# Major and medium distros which we are missing would include Mint, CentOS, -# RHEL, Raspbian, Cygwin, OpenWrt, gNewSense, Trisquel and SteamOS. -#------------------------------------------------------------------------------ - - #other Linux - echo "ERROR - Unsupported or unidentified Linux distro." - echo "See https://docs.soliditylang.org/en/latest/installing-solidity.html for manual instructions." - echo "If you would like to get your distro working, that would be fantastic." - echo "Drop us a message at https://gitter.im/ethereum/solidity-dev." - exit 1 - ;; - esac - ;; - -#------------------------------------------------------------------------------ -# Other platform (not Linux, FreeBSD or macOS). -# Not sure what might end up here? -# Maybe OpenBSD, NetBSD, AIX, Solaris, HP-UX? -#------------------------------------------------------------------------------ - - *) - #other - echo "ERROR - Unsupported or unidentified operating system." - echo "See https://docs.soliditylang.org/en/latest/installing-solidity.html for manual instructions." - echo "If you would like to get your operating system working, that would be fantastic." - echo "Drop us a message at https://gitter.im/ethereum/solidity-dev." - ;; -esac From 99aa18c4f3d033422394902789a50c076fbdbad6 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 2 Nov 2021 17:48:59 +0100 Subject: [PATCH 0074/1748] Refactor: Only return output. --- .../backends/evm/ControlFlowGraphBuilder.cpp | 22 +++++++++---------- libyul/backends/evm/ControlFlowGraphBuilder.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 7e57b82571..66ee9fcd59 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -176,9 +176,9 @@ StackSlot ControlFlowGraphBuilder::operator()(Expression const& _expression) StackSlot ControlFlowGraphBuilder::operator()(FunctionCall const& _call) { - CFG::Operation const& operation = visitFunctionCall(_call); - yulAssert(operation.output.size() == 1, ""); - return operation.output.front(); + Stack const& output = visitFunctionCall(_call); + yulAssert(output.size() == 1, ""); + return output.front(); } void ControlFlowGraphBuilder::operator()(VariableDeclaration const& _varDecl) @@ -219,8 +219,8 @@ void ControlFlowGraphBuilder::operator()(ExpressionStatement const& _exprStmt) yulAssert(m_currentBlock, ""); std::visit(util::GenericVisitor{ [&](FunctionCall const& _call) { - CFG::Operation const& operation = visitFunctionCall(_call); - yulAssert(operation.output.empty(), ""); + Stack const& output = visitFunctionCall(_call); + yulAssert(output.empty(), ""); }, [&](auto const&) { yulAssert(false, ""); } }, _exprStmt.expression); @@ -418,7 +418,7 @@ void ControlFlowGraphBuilder::operator()(FunctionDefinition const& _function) } -CFG::Operation const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call) +Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call) { yulAssert(m_scope, ""); yulAssert(m_currentBlock, ""); @@ -439,7 +439,7 @@ CFG::Operation const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall co }) | ranges::to, // operation move(builtinCall) - }); + }).output; } else { @@ -456,7 +456,7 @@ CFG::Operation const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall co }) | ranges::to, // operation CFG::FunctionCall{_call.debugData, function, _call} - }); + }).output; } } @@ -464,9 +464,9 @@ Stack ControlFlowGraphBuilder::visitAssignmentRightHandSide(Expression const& _e { return std::visit(util::GenericVisitor{ [&](FunctionCall const& _call) -> Stack { - CFG::Operation const& operation = visitFunctionCall(_call); - yulAssert(_expectedSlotCount == operation.output.size(), ""); - return operation.output; + Stack const& output = visitFunctionCall(_call); + yulAssert(_expectedSlotCount == output.size(), ""); + return output; }, [&](auto const& _identifierOrLiteral) -> Stack { yulAssert(_expectedSlotCount == 1, ""); diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.h b/libyul/backends/evm/ControlFlowGraphBuilder.h index f99a879f6c..8a6ec07c58 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.h +++ b/libyul/backends/evm/ControlFlowGraphBuilder.h @@ -57,7 +57,7 @@ class ControlFlowGraphBuilder AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect ); - CFG::Operation const& visitFunctionCall(FunctionCall const&); + Stack const& visitFunctionCall(FunctionCall const&); Stack visitAssignmentRightHandSide(Expression const& _expression, size_t _expectedSlotCount); Scope::Function const& lookupFunction(YulString _name) const; From 929ed094ce5e8ab2561dcfe95a689007edd87c95 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 4 Nov 2021 13:38:21 +0100 Subject: [PATCH 0075/1748] Register functions earlier. --- .../backends/evm/ControlFlowGraphBuilder.cpp | 32 ++++++++++++------- libyul/backends/evm/ControlFlowGraphBuilder.h | 1 + 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.cpp b/libyul/backends/evm/ControlFlowGraphBuilder.cpp index 66ee9fcd59..df271bb8d8 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/ControlFlowGraphBuilder.cpp @@ -239,6 +239,9 @@ void ControlFlowGraphBuilder::operator()(ExpressionStatement const& _exprStmt) void ControlFlowGraphBuilder::operator()(Block const& _block) { ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get()); + for (auto const& statement: _block.statements) + if (auto const* function = get_if(&statement)) + registerFunction(*function); for (auto const& statement: _block.statements) std::visit(*this, statement); } @@ -386,11 +389,26 @@ void ControlFlowGraphBuilder::operator()(FunctionDefinition const& _function) Scope::Function& function = std::get(m_scope->identifiers.at(_function.name)); m_graph.functions.emplace_back(&function); + CFG::FunctionInfo& functionInfo = m_graph.functionInfo.at(&function); + + ControlFlowGraphBuilder builder{m_graph, m_info, m_dialect}; + builder.m_currentFunction = &functionInfo; + builder.m_currentBlock = functionInfo.entry; + builder(_function.body); + builder.m_currentBlock->exit = CFG::BasicBlock::FunctionReturn{debugDataOf(_function), &functionInfo}; +} + +void ControlFlowGraphBuilder::registerFunction(FunctionDefinition const& _function) +{ + yulAssert(m_scope, ""); + yulAssert(m_scope->identifiers.count(_function.name), ""); + Scope::Function& function = std::get(m_scope->identifiers.at(_function.name)); + yulAssert(m_info.scopes.at(&_function.body), ""); Scope* virtualFunctionScope = m_info.scopes.at(m_info.virtualBlocks.at(&_function).get()).get(); yulAssert(virtualFunctionScope, ""); - auto&& [it, inserted] = m_graph.functionInfo.emplace(std::make_pair(&function, CFG::FunctionInfo{ + bool inserted = m_graph.functionInfo.emplace(std::make_pair(&function, CFG::FunctionInfo{ _function.debugData, function, &m_graph.makeBlock(debugDataOf(_function.body)), @@ -406,18 +424,10 @@ void ControlFlowGraphBuilder::operator()(FunctionDefinition const& _function) _retVar.debugData }; }) | ranges::to - })); - yulAssert(inserted, ""); - CFG::FunctionInfo& functionInfo = it->second; - - ControlFlowGraphBuilder builder{m_graph, m_info, m_dialect}; - builder.m_currentFunction = &functionInfo; - builder.m_currentBlock = functionInfo.entry; - builder(_function.body); - builder.m_currentBlock->exit = CFG::BasicBlock::FunctionReturn{debugDataOf(_function), &functionInfo}; + })).second; + yulAssert(inserted); } - Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call) { yulAssert(m_scope, ""); diff --git a/libyul/backends/evm/ControlFlowGraphBuilder.h b/libyul/backends/evm/ControlFlowGraphBuilder.h index 8a6ec07c58..2a99cfe5ba 100644 --- a/libyul/backends/evm/ControlFlowGraphBuilder.h +++ b/libyul/backends/evm/ControlFlowGraphBuilder.h @@ -57,6 +57,7 @@ class ControlFlowGraphBuilder AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect ); + void registerFunction(FunctionDefinition const& _function); Stack const& visitFunctionCall(FunctionCall const&); Stack visitAssignmentRightHandSide(Expression const& _expression, size_t _expectedSlotCount); From e7deedb7074ef8c68a49b30ef5e7503cf3eeca00 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Nov 2021 11:17:28 +0100 Subject: [PATCH 0076/1748] Pass emscripten linker options only when linking. --- Changelog.md | 1 + cmake/EthCompilerSettings.cmake | 26 ++++++++++++++------------ libsolc/CMakeLists.txt | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Changelog.md b/Changelog.md index b02bb80c30..80bd749c7e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -32,6 +32,7 @@ Bugfixes: Build System: + * Pass linker-only emscripten options only when linking. * Remove obsolete compatibility workaround for emscripten builds. diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 0695c56a31..25c32f8896 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -111,39 +111,41 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA # http://stackoverflow.com/questions/21617158/how-to-silence-unused-command-line-argument-error-with-clang-without-disabling-i add_compile_options(-Qunused-arguments) elseif(EMSCRIPTEN) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --memory-init-file 0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --memory-init-file 0") # Leave only exported symbols as public and aggressively remove others set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections -fvisibility=hidden") # Optimisation level set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") # Re-enable exception catching (optimisations above -O1 disable it) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0") # Remove any code related to exit (such as atexit) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s EXIT_RUNTIME=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXIT_RUNTIME=0") # Remove any code related to filesystem access - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s FILESYSTEM=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s FILESYSTEM=0") # Allow memory growth, but disable some optimisations - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1") # Disable eval() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s DYNAMIC_EXECUTION=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DYNAMIC_EXECUTION=0") # Disable greedy exception catcher - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NODEJS_CATCH_EXIT=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s NODEJS_CATCH_EXIT=0") # Abort if linking results in any undefined symbols # Note: this is on by default in the CMake Emscripten module which we aren't using - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1") # Disallow deprecated emscripten build options. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s STRICT=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s STRICT=1") # Export the Emscripten-generated auxiliary methods which are needed by solc-js. # Which methods of libsolc itself are exported is specified in libsolc/CMakeLists.txt. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS=['cwrap','addFunction','removeFunction','UTF8ToString','lengthBytesUTF8','stringToUTF8','setValue']") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS=['cwrap','addFunction','removeFunction','UTF8ToString','lengthBytesUTF8','stringToUTF8','setValue']") # Build for webassembly target. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM=1") # Set webassembly build to synchronous loading. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM_ASYNC_COMPILATION=0") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM_ASYNC_COMPILATION=0") # Output a single js file with the wasm binary embedded as base64 string. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s SINGLE_FILE=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s SINGLE_FILE=1") # Allow new functions to be added to the wasm module via addFunction. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_TABLE_GROWTH=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_TABLE_GROWTH=1") # Disable warnings about not being pure asm.js due to memory growth. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-almost-asm") endif() diff --git a/libsolc/CMakeLists.txt b/libsolc/CMakeLists.txt index 36dee4e249..776b97ca50 100644 --- a/libsolc/CMakeLists.txt +++ b/libsolc/CMakeLists.txt @@ -2,7 +2,7 @@ if (EMSCRIPTEN) # Specify which functions to export in soljson.js. # Note that additional Emscripten-generated methods needed by solc-js are # defined to be exported in cmake/EthCompilerSettings.cmake. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s EXPORTED_FUNCTIONS='[\"_solidity_license\",\"_solidity_version\",\"_solidity_compile\",\"_solidity_alloc\",\"_solidity_free\",\"_solidity_reset\"]'") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXPORTED_FUNCTIONS='[\"_solidity_license\",\"_solidity_version\",\"_solidity_compile\",\"_solidity_alloc\",\"_solidity_free\",\"_solidity_reset\"]'") add_executable(soljson libsolc.cpp libsolc.h) target_link_libraries(soljson PRIVATE solidity) else() From dd8f12760b0ef6630a40d3a4d5eec6a3aadbe95f Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 4 Nov 2021 15:40:57 +0100 Subject: [PATCH 0077/1748] Introduce forEach for yul ast nodes. --- libyul/CMakeLists.txt | 2 - libyul/ControlFlowSideEffectsCollector.cpp | 2 - libyul/optimiser/ASTWalker.h | 31 +++++++++++++ libyul/optimiser/DataFlowAnalyzer.cpp | 26 +++++------ .../optimiser/FunctionDefinitionCollector.cpp | 36 --------------- .../optimiser/FunctionDefinitionCollector.h | 44 ------------------- libyul/optimiser/NameCollector.cpp | 26 ++++++++--- libyul/optimiser/NameCollector.h | 22 ++++------ libyul/optimiser/SSATransform.cpp | 22 +++------- libyul/optimiser/StackLimitEvader.cpp | 4 +- libyul/optimiser/StackToMemoryMover.cpp | 4 +- 11 files changed, 79 insertions(+), 140 deletions(-) delete mode 100644 libyul/optimiser/FunctionDefinitionCollector.cpp delete mode 100644 libyul/optimiser/FunctionDefinitionCollector.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 30b97b5f78..3c980fbb85 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -140,8 +140,6 @@ add_library(yul optimiser/FullInliner.h optimiser/FunctionCallFinder.cpp optimiser/FunctionCallFinder.h - optimiser/FunctionDefinitionCollector.cpp - optimiser/FunctionDefinitionCollector.h optimiser/FunctionGrouper.cpp optimiser/FunctionGrouper.h optimiser/FunctionHoister.cpp diff --git a/libyul/ControlFlowSideEffectsCollector.cpp b/libyul/ControlFlowSideEffectsCollector.cpp index f907f83f5b..bdcf70a783 100644 --- a/libyul/ControlFlowSideEffectsCollector.cpp +++ b/libyul/ControlFlowSideEffectsCollector.cpp @@ -18,8 +18,6 @@ #include -#include - #include #include diff --git a/libyul/optimiser/ASTWalker.h b/libyul/optimiser/ASTWalker.h index 107658dfc1..cd98a90cad 100644 --- a/libyul/optimiser/ASTWalker.h +++ b/libyul/optimiser/ASTWalker.h @@ -102,4 +102,35 @@ class ASTModifier } }; +namespace detail +{ +template < + typename Node, + typename Visitor, + typename Base = std::conditional_t, ASTWalker, ASTModifier> +> +struct ForEach: Base +{ + template + ForEach(Callable&& _visitor): visitor(std::forward(_visitor)) {} + + using Base::operator(); + void operator()(Node& _node) override + { + visitor(_node); + Base::operator()(_node); + } + + Visitor visitor; +}; +} + +/// Helper function that traverses the AST and calls the visitor for each +/// node of a specific type. +template +void forEach(Entry&& _entry, Visitor&& _visitor) +{ + detail::ForEach>{std::forward(_visitor)}(std::forward(_entry)); +} + } diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp index c6d9decaf6..af25cde592 100644 --- a/libyul/optimiser/DataFlowAnalyzer.cpp +++ b/libyul/optimiser/DataFlowAnalyzer.cpp @@ -45,9 +45,9 @@ DataFlowAnalyzer::DataFlowAnalyzer( Dialect const& _dialect, map _functionSideEffects ): -m_dialect(_dialect), -m_functionSideEffects(std::move(_functionSideEffects)), -m_knowledgeBase(_dialect, m_value) + m_dialect(_dialect), + m_functionSideEffects(std::move(_functionSideEffects)), + m_knowledgeBase(_dialect, m_value) { if (auto const* builtin = _dialect.memoryStoreFunction(YulString{})) m_storeFunctionName[static_cast(StoreLoadLocation::Memory)] = builtin->name; @@ -123,9 +123,7 @@ void DataFlowAnalyzer::operator()(If& _if) joinKnowledge(storage, memory); - Assignments assignments; - assignments(_if.body); - clearValues(assignments.names()); + clearValues(assignedVariableNames(_if.body)); } void DataFlowAnalyzer::operator()(Switch& _switch) @@ -140,11 +138,10 @@ void DataFlowAnalyzer::operator()(Switch& _switch) (*this)(_case.body); joinKnowledge(storage, memory); - Assignments assignments; - assignments(_case.body); - assignedVariables += assignments.names(); + set variables = assignedVariableNames(_case.body); + assignedVariables += variables; // This is a little too destructive, we could retain the old values. - clearValues(assignments.names()); + clearValues(variables); clearKnowledgeIfInvalidated(_case.body); } for (auto& _case: _switch.cases) @@ -190,10 +187,9 @@ void DataFlowAnalyzer::operator()(ForLoop& _for) AssignmentsSinceContinue assignmentsSinceCont; assignmentsSinceCont(_for.body); - Assignments assignments; - assignments(_for.body); - assignments(_for.post); - clearValues(assignments.names()); + set assignedVariables = + assignedVariableNames(_for.body) + assignedVariableNames(_for.post); + clearValues(assignedVariables); // break/continue are tricky for storage and thus we almost always clear here. clearKnowledgeIfInvalidated(*_for.condition); @@ -205,7 +201,7 @@ void DataFlowAnalyzer::operator()(ForLoop& _for) clearValues(assignmentsSinceCont.names()); clearKnowledgeIfInvalidated(_for.body); (*this)(_for.post); - clearValues(assignments.names()); + clearValues(assignedVariables); clearKnowledgeIfInvalidated(*_for.condition); clearKnowledgeIfInvalidated(_for.post); clearKnowledgeIfInvalidated(_for.body); diff --git a/libyul/optimiser/FunctionDefinitionCollector.cpp b/libyul/optimiser/FunctionDefinitionCollector.cpp deleted file mode 100644 index dff57a32aa..0000000000 --- a/libyul/optimiser/FunctionDefinitionCollector.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ - -#include -#include - -using namespace std; -using namespace solidity; -using namespace solidity::yul; - -map FunctionDefinitionCollector::run(Block const& _block) -{ - FunctionDefinitionCollector functionDefinitionCollector; - functionDefinitionCollector(_block); - return functionDefinitionCollector.m_functionDefinitions; -} - -void FunctionDefinitionCollector::operator()(FunctionDefinition const& _functionDefinition) -{ - m_functionDefinitions[_functionDefinition.name] = &_functionDefinition; - ASTWalker::operator()(_functionDefinition); -} diff --git a/libyul/optimiser/FunctionDefinitionCollector.h b/libyul/optimiser/FunctionDefinitionCollector.h deleted file mode 100644 index c9828aced3..0000000000 --- a/libyul/optimiser/FunctionDefinitionCollector.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . -*/ -/** - * AST walker that finds all function definitions and stores them into a map indexed by the function names. - */ -#pragma once - -#include - -#include - -namespace solidity::yul -{ - -/** - * AST walker that finds all function definitions and stores them into a map indexed by the function names. - * - * Prerequisite: Disambiguator - */ -class FunctionDefinitionCollector: ASTWalker -{ -public: - static std::map run(Block const& _block); -private: - using ASTWalker::operator(); - void operator()(FunctionDefinition const& _functionDefinition) override; - std::map m_functionDefinitions; -}; - -} diff --git a/libyul/optimiser/NameCollector.cpp b/libyul/optimiser/NameCollector.cpp index 69e627fbb5..eca509f43c 100644 --- a/libyul/optimiser/NameCollector.cpp +++ b/libyul/optimiser/NameCollector.cpp @@ -78,13 +78,6 @@ map ReferencesCounter::countReferences(Expression const& _exp return counter.references(); } -void Assignments::operator()(Assignment const& _assignment) -{ - for (auto const& var: _assignment.variableNames) - m_names.emplace(var.name); -} - - void AssignmentsSinceContinue::operator()(ForLoop const& _forLoop) { m_forLoopDepth++; @@ -109,3 +102,22 @@ void AssignmentsSinceContinue::operator()(FunctionDefinition const&) { yulAssert(false, ""); } + +std::set solidity::yul::assignedVariableNames(Block const& _code) +{ + std::set names; + forEach(_code, [&](Assignment const& _assignment) { + for (auto const& var: _assignment.variableNames) + names.emplace(var.name); + }); + return names; +} + +map solidity::yul::allFunctionDefinitions(Block const& _block) +{ + std::map result; + forEach(_block, [&](FunctionDefinition const& _function) { + result[_function.name] = &_function; + }); + return result; +} diff --git a/libyul/optimiser/NameCollector.h b/libyul/optimiser/NameCollector.h index 17afcec1b1..8c9dc14ff8 100644 --- a/libyul/optimiser/NameCollector.h +++ b/libyul/optimiser/NameCollector.h @@ -91,20 +91,6 @@ class ReferencesCounter: public ASTWalker std::map m_references; }; -/** - * Specific AST walker that finds all variables that are assigned to. - */ -class Assignments: public ASTWalker -{ -public: - using ASTWalker::operator (); - void operator()(Assignment const& _assignment) override; - - std::set const& names() const { return m_names; } -private: - std::set m_names; -}; - /** * Collects all names from a given continue statement on onwards. * @@ -130,4 +116,12 @@ class AssignmentsSinceContinue: public ASTWalker std::set m_names; }; +/// @returns the names of all variables that are assigned to inside @a _code. +/// (ignores variable declarations) +std::set assignedVariableNames(Block const& _code); + +/// @returns all function definitions anywhere in the AST. +/// Requires disambiguated source. +std::map allFunctionDefinitions(Block const& _block); + } diff --git a/libyul/optimiser/SSATransform.cpp b/libyul/optimiser/SSATransform.cpp index f0ce68c921..d86e6fbee1 100644 --- a/libyul/optimiser/SSATransform.cpp +++ b/libyul/optimiser/SSATransform.cpp @@ -196,12 +196,7 @@ void IntroduceControlFlowSSA::operator()(ForLoop& _for) { yulAssert(_for.pre.statements.empty(), "For loop init rewriter not run."); - Assignments assignments; - assignments(_for.body); - assignments(_for.post); - - - for (auto const& var: assignments.names()) + for (auto const& var: assignedVariableNames(_for.body) + assignedVariableNames(_for.post)) if (m_variablesInScope.count(var)) m_variablesToReassign.insert(var); @@ -359,11 +354,7 @@ void PropagateValues::operator()(ForLoop& _for) { yulAssert(_for.pre.statements.empty(), "For loop init rewriter not run."); - Assignments assignments; - assignments(_for.body); - assignments(_for.post); - - for (auto const& var: assignments.names()) + for (auto const& var: assignedVariableNames(_for.body) + assignedVariableNames(_for.post)) m_currentVariableValues.erase(var); visit(*_for.condition); @@ -389,11 +380,10 @@ void PropagateValues::operator()(Block& _block) void SSATransform::run(OptimiserStepContext& _context, Block& _ast) { TypeInfo typeInfo(_context.dialect, _ast); - Assignments assignments; - assignments(_ast); - IntroduceSSA{_context.dispenser, assignments.names(), typeInfo}(_ast); - IntroduceControlFlowSSA{_context.dispenser, assignments.names(), typeInfo}(_ast); - PropagateValues{assignments.names()}(_ast); + set assignedVariables = assignedVariableNames(_ast); + IntroduceSSA{_context.dispenser, assignedVariables, typeInfo}(_ast); + IntroduceControlFlowSSA{_context.dispenser, assignedVariables, typeInfo}(_ast); + PropagateValues{assignedVariables}(_ast); } diff --git a/libyul/optimiser/StackLimitEvader.cpp b/libyul/optimiser/StackLimitEvader.cpp index b77bd4f388..b4b9d5469a 100644 --- a/libyul/optimiser/StackLimitEvader.cpp +++ b/libyul/optimiser/StackLimitEvader.cpp @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -193,7 +193,7 @@ void StackLimitEvader::run( if (_unreachableVariables.count(function)) return; - map functionDefinitions = FunctionDefinitionCollector::run(*_object.code); + map functionDefinitions = allFunctionDefinitions(*_object.code); MemoryOffsetAllocator memoryOffsetAllocator{_unreachableVariables, callGraph.functionCalls, functionDefinitions}; uint64_t requiredSlots = memoryOffsetAllocator.run(); diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index dcc5f45f6e..4256809236 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -15,7 +15,7 @@ along with solidity. If not, see . */ #include -#include +#include #include #include @@ -87,7 +87,7 @@ void StackToMemoryMover::run( _context, memoryOffsetTracker, util::applyMap( - FunctionDefinitionCollector::run(_block), + allFunctionDefinitions(_block), util::mapTuple([](YulString _name, FunctionDefinition const* _funDef) { return make_pair(_name, _funDef->returnVariables); }), From 25c41546ee03f9567d67068dcc636c09367e9a32 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 3 Nov 2021 11:08:45 +0100 Subject: [PATCH 0078/1748] Function reference resolver. --- libyul/CMakeLists.txt | 2 + libyul/FunctionReferenceResolver.cpp | 60 ++++++++++++++++++++++++++++ libyul/FunctionReferenceResolver.h | 48 ++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 libyul/FunctionReferenceResolver.cpp create mode 100644 libyul/FunctionReferenceResolver.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 3c980fbb85..039e24ea91 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -40,6 +40,8 @@ add_library(yul Dialect.cpp Dialect.h Exceptions.h + FunctionReferenceResolver.cpp + FunctionReferenceResolver.h Object.cpp Object.h ObjectParser.cpp diff --git a/libyul/FunctionReferenceResolver.cpp b/libyul/FunctionReferenceResolver.cpp new file mode 100644 index 0000000000..5df94237a3 --- /dev/null +++ b/libyul/FunctionReferenceResolver.cpp @@ -0,0 +1,60 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include +#include + +#include + +using namespace std; +using namespace solidity::yul; +using namespace solidity::util; + +FunctionReferenceResolver::FunctionReferenceResolver(Block const& _ast) +{ + (*this)(_ast); + yulAssert(m_scopes.empty()); +} + +void FunctionReferenceResolver::operator()(FunctionCall const& _functionCall) +{ + for (auto&& scope: m_scopes | ranges::views::reverse) + if (FunctionDefinition const** function = util::valueOrNullptr(scope, _functionCall.functionName.name)) + { + m_functionReferences[&_functionCall] = *function; + break; + } + + // If we did not find anything, it was a builtin call. + + ASTWalker::operator()(_functionCall); +} + +void FunctionReferenceResolver::operator()(Block const& _block) +{ + m_scopes.emplace_back(); + for (auto const& statement: _block.statements) + if (auto const* function = get_if(&statement)) + m_scopes.back()[function->name] = function; + + ASTWalker::operator()(_block); + + m_scopes.pop_back(); +} diff --git a/libyul/FunctionReferenceResolver.h b/libyul/FunctionReferenceResolver.h new file mode 100644 index 0000000000..8c1385adb6 --- /dev/null +++ b/libyul/FunctionReferenceResolver.h @@ -0,0 +1,48 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +namespace solidity::yul +{ + +/** + * Resolves references to user-defined functions in function calls. + * Assumes the code is correct, i.e. does not check for references to be valid or unique. + * + * Be careful not to iterate over the result - it is not deterministic. + */ +class FunctionReferenceResolver: private ASTWalker +{ +public: + explicit FunctionReferenceResolver(Block const& _ast); + std::map const& references() const { return m_functionReferences; } + +private: + using ASTWalker::operator(); + void operator()(FunctionCall const& _functionCall) override; + void operator()(Block const& _block) override; + + std::map m_functionReferences; + std::vector> m_scopes; +}; + + +} From 776ae466bcadda76fdffd976faa835f39995305a Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 3 Nov 2021 15:00:37 +0100 Subject: [PATCH 0079/1748] Control flow side effects on non-disambiguated source. --- libyul/ControlFlowSideEffectsCollector.cpp | 108 ++++++++++-------- libyul/ControlFlowSideEffectsCollector.h | 39 ++++--- libyul/optimiser/ConditionalSimplifier.cpp | 6 +- libyul/optimiser/ConditionalSimplifier.h | 6 +- libyul/optimiser/ConditionalUnsimplifier.cpp | 6 +- libyul/optimiser/DeadCodeEliminator.cpp | 2 +- libyul/optimiser/DeadCodeEliminator.h | 8 +- test/libyul/ControlFlowSideEffectsTest.cpp | 21 ++-- .../nondisambiguated.yul | 19 +++ 9 files changed, 128 insertions(+), 87 deletions(-) create mode 100644 test/libyul/controlFlowSideEffects/nondisambiguated.yul diff --git a/libyul/ControlFlowSideEffectsCollector.cpp b/libyul/ControlFlowSideEffectsCollector.cpp index bdcf70a783..6e96712a08 100644 --- a/libyul/ControlFlowSideEffectsCollector.cpp +++ b/libyul/ControlFlowSideEffectsCollector.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -35,16 +36,15 @@ using namespace solidity::yul; ControlFlowBuilder::ControlFlowBuilder(Block const& _ast) { - for (auto const& statement: _ast.statements) - if (auto const* function = get_if(&statement)) - (*this)(*function); + m_currentNode = newNode(); + (*this)(_ast); } void ControlFlowBuilder::operator()(FunctionCall const& _functionCall) { walkVector(_functionCall.arguments | ranges::views::reverse); newConnectedNode(); - m_currentNode->functionCall = _functionCall.functionName.name; + m_currentNode->functionCall = &_functionCall; } void ControlFlowBuilder::operator()(If const& _if) @@ -78,7 +78,9 @@ void ControlFlowBuilder::operator()(Switch const& _switch) void ControlFlowBuilder::operator()(FunctionDefinition const& _function) { ScopedSaveAndRestore currentNode(m_currentNode, nullptr); - yulAssert(!m_leave && !m_break && !m_continue, "Function hoister has not been used."); + ScopedSaveAndRestore leave(m_leave, nullptr); + ScopedSaveAndRestore _break(m_break, nullptr); + ScopedSaveAndRestore _continue(m_continue, nullptr); FunctionFlow flow; flow.exit = newNode(); @@ -90,7 +92,7 @@ void ControlFlowBuilder::operator()(FunctionDefinition const& _function) m_currentNode->successors.emplace_back(flow.exit); - m_functionFlows[_function.name] = move(flow); + m_functionFlows[&_function] = move(flow); m_leave = nullptr; } @@ -164,14 +166,17 @@ ControlFlowSideEffectsCollector::ControlFlowSideEffectsCollector( Block const& _ast ): m_dialect(_dialect), - m_cfgBuilder(_ast) + m_cfgBuilder(_ast), + m_functionReferences(FunctionReferenceResolver{_ast}.references()) { - for (auto&& [name, flow]: m_cfgBuilder.functionFlows()) + for (auto&& [function, flow]: m_cfgBuilder.functionFlows()) { yulAssert(!flow.entry->functionCall); - m_processedNodes[name] = {}; - m_pendingNodes[name].push_front(flow.entry); - m_functionSideEffects[name] = {false, false, false}; + yulAssert(function); + m_processedNodes[function] = {}; + m_pendingNodes[function].push_front(flow.entry); + m_functionSideEffects[function] = {false, false, false}; + m_functionCalls[function] = {}; } // Process functions while we have progress. For now, we are only interested @@ -180,8 +185,8 @@ ControlFlowSideEffectsCollector::ControlFlowSideEffectsCollector( while (progress) { progress = false; - for (auto const& functionName: m_pendingNodes | ranges::views::keys) - if (processFunction(functionName)) + for (FunctionDefinition const* function: m_pendingNodes | ranges::views::keys) + if (processFunction(*function)) progress = true; } @@ -190,57 +195,64 @@ ControlFlowSideEffectsCollector::ControlFlowSideEffectsCollector( // If we have not set `canContinue` by now, the function's exit // is not reachable. - for (auto&& [functionName, calls]: m_functionCalls) + // Now it is sufficient to handle the reachable function calls (`m_functionCalls`), + // we do not have to consider the control-flow graph anymore. + for (auto&& [function, calls]: m_functionCalls) { - ControlFlowSideEffects& sideEffects = m_functionSideEffects[functionName]; - auto _visit = [&, visited = std::set{}](YulString _function, auto&& _recurse) mutable { - if (sideEffects.canTerminate && sideEffects.canRevert) + yulAssert(function); + ControlFlowSideEffects& functionSideEffects = m_functionSideEffects[function]; + auto _visit = [&, visited = std::set{}](FunctionDefinition const& _function, auto&& _recurse) mutable { + // Worst side-effects already, stop searching. + if (functionSideEffects.canTerminate && functionSideEffects.canRevert) return; - if (!visited.insert(_function).second) + if (!visited.insert(&_function).second) return; - ControlFlowSideEffects const* calledSideEffects = nullptr; - if (BuiltinFunction const* f = _dialect.builtin(_function)) - calledSideEffects = &f->controlFlowSideEffects; - else - calledSideEffects = &m_functionSideEffects.at(_function); - - if (calledSideEffects->canTerminate) - sideEffects.canTerminate = true; - if (calledSideEffects->canRevert) - sideEffects.canRevert = true; - - set emptySet; - for (YulString callee: util::valueOrDefault(m_functionCalls, _function, emptySet)) - _recurse(callee, _recurse); + for (FunctionCall const* call: m_functionCalls.at(&_function)) + { + ControlFlowSideEffects const& calledSideEffects = sideEffects(*call); + if (calledSideEffects.canTerminate) + functionSideEffects.canTerminate = true; + if (calledSideEffects.canRevert) + functionSideEffects.canRevert = true; + + if (m_functionReferences.count(call)) + _recurse(*m_functionReferences.at(call), _recurse); + } }; - for (auto const& call: calls) - _visit(call, _visit); + _visit(*function, _visit); } +} +map ControlFlowSideEffectsCollector::functionSideEffectsNamed() const +{ + map result; + for (auto&& [function, sideEffects]: m_functionSideEffects) + yulAssert(result.insert({function->name, sideEffects}).second); + return result; } -bool ControlFlowSideEffectsCollector::processFunction(YulString _name) +bool ControlFlowSideEffectsCollector::processFunction(FunctionDefinition const& _function) { bool progress = false; - while (ControlFlowNode const* node = nextProcessableNode(_name)) + while (ControlFlowNode const* node = nextProcessableNode(_function)) { - if (node == m_cfgBuilder.functionFlows().at(_name).exit) + if (node == m_cfgBuilder.functionFlows().at(&_function).exit) { - m_functionSideEffects[_name].canContinue = true; + m_functionSideEffects[&_function].canContinue = true; return true; } for (ControlFlowNode const* s: node->successors) - recordReachabilityAndQueue(_name, s); + recordReachabilityAndQueue(_function, s); progress = true; } return progress; } -ControlFlowNode const* ControlFlowSideEffectsCollector::nextProcessableNode(YulString _functionName) +ControlFlowNode const* ControlFlowSideEffectsCollector::nextProcessableNode(FunctionDefinition const& _function) { - std::list& nodes = m_pendingNodes[_functionName]; + std::list& nodes = m_pendingNodes[&_function]; auto it = ranges::find_if(nodes, [this](ControlFlowNode const* _node) { return !_node->functionCall || sideEffects(*_node->functionCall).canContinue; }); @@ -252,22 +264,22 @@ ControlFlowNode const* ControlFlowSideEffectsCollector::nextProcessableNode(YulS return node; } -ControlFlowSideEffects const& ControlFlowSideEffectsCollector::sideEffects(YulString _functionName) const +ControlFlowSideEffects const& ControlFlowSideEffectsCollector::sideEffects(FunctionCall const& _call) const { - if (auto const* builtin = m_dialect.builtin(_functionName)) + if (auto const* builtin = m_dialect.builtin(_call.functionName.name)) return builtin->controlFlowSideEffects; else - return m_functionSideEffects.at(_functionName); + return m_functionSideEffects.at(m_functionReferences.at(&_call)); } void ControlFlowSideEffectsCollector::recordReachabilityAndQueue( - YulString _functionName, + FunctionDefinition const& _function, ControlFlowNode const* _node ) { if (_node->functionCall) - m_functionCalls[_functionName].insert(*_node->functionCall); - if (m_processedNodes[_functionName].insert(_node).second) - m_pendingNodes.at(_functionName).push_front(_node); + m_functionCalls[&_function].insert(_node->functionCall); + if (m_processedNodes[&_function].insert(_node).second) + m_pendingNodes.at(&_function).push_front(_node); } diff --git a/libyul/ControlFlowSideEffectsCollector.h b/libyul/ControlFlowSideEffectsCollector.h index f130294bae..a4ab2bfae7 100644 --- a/libyul/ControlFlowSideEffectsCollector.h +++ b/libyul/ControlFlowSideEffectsCollector.h @@ -34,8 +34,8 @@ struct Dialect; struct ControlFlowNode { std::vector successors; - /// Name of the called function if the node calls a function. - std::optional functionCall; + /// Function call AST node, if present. + FunctionCall const* functionCall = nullptr; }; /** @@ -56,7 +56,7 @@ class ControlFlowBuilder: private ASTWalker /// Computes the control-flows of all function defined in the block. /// Assumes the functions are hoisted to the topmost block. explicit ControlFlowBuilder(Block const& _ast); - std::map const& functionFlows() const { return m_functionFlows; } + std::map const& functionFlows() const { return m_functionFlows; } private: using ASTWalker::operator(); @@ -79,12 +79,14 @@ class ControlFlowBuilder: private ASTWalker ControlFlowNode const* m_break = nullptr; ControlFlowNode const* m_continue = nullptr; - std::map m_functionFlows; + std::map m_functionFlows; }; /** - * Requires: Disambiguator, Function Hoister. + * Computes control-flow side-effects for user-defined functions. + * Source does not have to be disambiguated, unless you want the side-effects + * based on function names. */ class ControlFlowSideEffectsCollector { @@ -94,36 +96,43 @@ class ControlFlowSideEffectsCollector Block const& _ast ); - std::map const& functionSideEffects() const + std::map const& functionSideEffects() const { return m_functionSideEffects; } + /// Returns the side effects by function name, requires unique function names. + std::map functionSideEffectsNamed() const; private: /// @returns false if nothing could be processed. - bool processFunction(YulString _name); + bool processFunction(FunctionDefinition const& _function); /// @returns the next pending node of the function that is not /// a function call to a function that might not continue. /// De-queues the node or returns nullptr if no such node is found. - ControlFlowNode const* nextProcessableNode(YulString _functionName); + ControlFlowNode const* nextProcessableNode(FunctionDefinition const& _function); /// @returns the side-effects of either a builtin call or a user defined function /// call (as far as already computed). - ControlFlowSideEffects const& sideEffects(YulString _functionName) const; + ControlFlowSideEffects const& sideEffects(FunctionCall const& _call) const; /// Queues the given node to be processed (if not already visited) /// and if it is a function call, records that `_functionName` calls /// `*_node->functionCall`. - void recordReachabilityAndQueue(YulString _functionName, ControlFlowNode const* _node); + void recordReachabilityAndQueue(FunctionDefinition const& _function, ControlFlowNode const* _node); Dialect const& m_dialect; ControlFlowBuilder m_cfgBuilder; - std::map m_functionSideEffects; - std::map> m_pendingNodes; - std::map> m_processedNodes; - /// `x` is in `m_functionCalls[y]` if a direct call to `x` is reachable inside `y` - std::map> m_functionCalls; + /// Function references, but only for calls to user-defined functions. + std::map m_functionReferences; + /// Side effects of user-defined functions, is being constructod. + std::map m_functionSideEffects; + /// Control flow nodes still to process, per function. + std::map> m_pendingNodes; + /// Control flow nodes already processed, per function. + std::map> m_processedNodes; + /// Set of reachable function calls nodes in each function (including calls to builtins). + std::map> m_functionCalls; }; diff --git a/libyul/optimiser/ConditionalSimplifier.cpp b/libyul/optimiser/ConditionalSimplifier.cpp index 3a2e8aa4e4..62d36520a2 100644 --- a/libyul/optimiser/ConditionalSimplifier.cpp +++ b/libyul/optimiser/ConditionalSimplifier.cpp @@ -29,8 +29,10 @@ using namespace solidity::util; void ConditionalSimplifier::run(OptimiserStepContext& _context, Block& _ast) { - ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); - ConditionalSimplifier{_context.dialect, sideEffects.functionSideEffects()}(_ast); + ConditionalSimplifier{ + _context.dialect, + ControlFlowSideEffectsCollector{_context.dialect, _ast}.functionSideEffectsNamed() + }(_ast); } void ConditionalSimplifier::operator()(Switch& _switch) diff --git a/libyul/optimiser/ConditionalSimplifier.h b/libyul/optimiser/ConditionalSimplifier.h index 57a6696c4b..5df56476a3 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 const& _sideEffects + std::map _sideEffects ): - m_dialect(_dialect), m_functionSideEffects(_sideEffects) + m_dialect(_dialect), m_functionSideEffects(move(_sideEffects)) {} Dialect const& m_dialect; - std::map const& m_functionSideEffects; + std::map m_functionSideEffects; }; } diff --git a/libyul/optimiser/ConditionalUnsimplifier.cpp b/libyul/optimiser/ConditionalUnsimplifier.cpp index 752e06918b..ef640ed7c9 100644 --- a/libyul/optimiser/ConditionalUnsimplifier.cpp +++ b/libyul/optimiser/ConditionalUnsimplifier.cpp @@ -30,8 +30,10 @@ using namespace solidity::util; void ConditionalUnsimplifier::run(OptimiserStepContext& _context, Block& _ast) { - ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); - ConditionalUnsimplifier{_context.dialect, sideEffects.functionSideEffects()}(_ast); + ConditionalUnsimplifier{ + _context.dialect, + ControlFlowSideEffectsCollector{_context.dialect, _ast}.functionSideEffectsNamed() + }(_ast); } void ConditionalUnsimplifier::operator()(Switch& _switch) diff --git a/libyul/optimiser/DeadCodeEliminator.cpp b/libyul/optimiser/DeadCodeEliminator.cpp index ad127a9108..af84546843 100644 --- a/libyul/optimiser/DeadCodeEliminator.cpp +++ b/libyul/optimiser/DeadCodeEliminator.cpp @@ -40,7 +40,7 @@ void DeadCodeEliminator::run(OptimiserStepContext& _context, Block& _ast) ControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast); DeadCodeEliminator{ _context.dialect, - sideEffects.functionSideEffects() + sideEffects.functionSideEffectsNamed() }(_ast); } diff --git a/libyul/optimiser/DeadCodeEliminator.h b/libyul/optimiser/DeadCodeEliminator.h index 98202fc943..2c166a8361 100644 --- a/libyul/optimiser/DeadCodeEliminator.h +++ b/libyul/optimiser/DeadCodeEliminator.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -31,7 +32,6 @@ namespace solidity::yul { struct Dialect; struct OptimiserStepContext; -struct ControlFlowSideEffects; /** * Optimisation stage that removes unreachable code @@ -62,11 +62,11 @@ class DeadCodeEliminator: public ASTModifier private: DeadCodeEliminator( Dialect const& _dialect, - std::map const& _sideEffects - ): m_dialect(_dialect), m_functionSideEffects(_sideEffects) {} + std::map _sideEffects + ): m_dialect(_dialect), m_functionSideEffects(move(_sideEffects)) {} Dialect const& m_dialect; - std::map const& m_functionSideEffects; + std::map m_functionSideEffects; }; } diff --git a/test/libyul/ControlFlowSideEffectsTest.cpp b/test/libyul/ControlFlowSideEffectsTest.cpp index aff3c564d9..ce6c18c358 100644 --- a/test/libyul/ControlFlowSideEffectsTest.cpp +++ b/test/libyul/ControlFlowSideEffectsTest.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -61,19 +62,15 @@ TestCase::TestResult ControlFlowSideEffectsTest::run(ostream& _stream, string co if (!obj.code) BOOST_THROW_EXCEPTION(runtime_error("Parsing input failed.")); - std::map sideEffects = - ControlFlowSideEffectsCollector( - EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), - *obj.code - ).functionSideEffects(); - - std::map controlFlowSideEffectsStr; - for (auto&& [fun, effects]: sideEffects) - controlFlowSideEffectsStr[fun.str()] = toString(effects); - + ControlFlowSideEffectsCollector sideEffects( + EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), + *obj.code + ); m_obtainedResult.clear(); - for (auto&& [functionName, effect]: controlFlowSideEffectsStr) - m_obtainedResult += functionName + (effect.empty() ? ":" : ": " + effect) + "\n"; + forEach(*obj.code, [&](FunctionDefinition const& _fun) { + string effectStr = toString(sideEffects.functionSideEffects().at(&_fun)); + m_obtainedResult += _fun.name.str() + (effectStr.empty() ? ":" : ": " + effectStr) + "\n"; + }); return checkResult(_stream, _linePrefix, _formatted); } diff --git a/test/libyul/controlFlowSideEffects/nondisambiguated.yul b/test/libyul/controlFlowSideEffects/nondisambiguated.yul new file mode 100644 index 0000000000..c3ed84bda1 --- /dev/null +++ b/test/libyul/controlFlowSideEffects/nondisambiguated.yul @@ -0,0 +1,19 @@ +{ + function a() { + { + function b() { if calldataloda(0) { return(0, 0) } } + b() + } + { + function b() { revert(0, 0) } + b() + } + } + function b() { + leave + revert(0, 0) + } +} +// ---- +// a: can revert +// b: can continue From 766d10b848684596e4fd6af026fa16d45b10ad18 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 3 Nov 2021 17:12:58 +0100 Subject: [PATCH 0080/1748] Tests. --- .../controlFlowSideEffects/nondisambiguated.yul | 14 +++++++++----- test/libyul/controlFlowSideEffects/recursion.yul | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test/libyul/controlFlowSideEffects/nondisambiguated.yul b/test/libyul/controlFlowSideEffects/nondisambiguated.yul index c3ed84bda1..4cc68c140e 100644 --- a/test/libyul/controlFlowSideEffects/nondisambiguated.yul +++ b/test/libyul/controlFlowSideEffects/nondisambiguated.yul @@ -1,7 +1,7 @@ { function a() { { - function b() { if calldataloda(0) { return(0, 0) } } + function b() { if calldataload(0) { return(0, 0) } } b() } { @@ -9,11 +9,15 @@ b() } } - function b() { - leave - revert(0, 0) + { + function b() { + leave + revert(0, 0) + } } } // ---- -// a: can revert +// a: can terminate, can revert +// b: can terminate, can continue +// b: can revert // b: can continue diff --git a/test/libyul/controlFlowSideEffects/recursion.yul b/test/libyul/controlFlowSideEffects/recursion.yul index c4176d502b..69cd4a2da8 100644 --- a/test/libyul/controlFlowSideEffects/recursion.yul +++ b/test/libyul/controlFlowSideEffects/recursion.yul @@ -31,7 +31,7 @@ // b: can revert // c: // d: -// reg: can continue // x: // y: // z: +// reg: can continue From 0ee131c937f48116c69cc0276abb1f24da6d999e Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Nov 2021 15:09:48 +0100 Subject: [PATCH 0081/1748] Update emscripten Dockerfile. --- .../docker/buildpack-deps/Dockerfile.emscripten | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.emscripten b/scripts/docker/buildpack-deps/Dockerfile.emscripten index 790a29634b..9a3ca36af4 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.emscripten +++ b/scripts/docker/buildpack-deps/Dockerfile.emscripten @@ -26,10 +26,14 @@ # contains a Makefile in the docker/ subdirectory that can be used to create the # required base image using: # -# make version=2.0.12 build +# make version=2.0.33 build # -FROM emscripten/emsdk:2.0.12 AS base -LABEL version="6" +# Note that emscripten is supposed to automatically install to $(em-config CACHE)/sysroot, but +# apparently this currently breaks due to conflicting compatibility headers. +# Using $(em-config CACHE)/sysroot/usr seems to work, though, and still has cmake find the +# dependencies automatically. +FROM emscripten/emsdk:2.0.33 AS base +LABEL version="7" ADD emscripten.jam /usr/src RUN set -ex; \ @@ -39,8 +43,8 @@ RUN set -ex; \ mkdir build; \ cd build; \ emcmake cmake \ + -DCMAKE_INSTALL_PREFIX=$(em-config CACHE)/sysroot/usr \ -DCMAKE_BUILD_TYPE=MinSizeRel \ - -DCMAKE_INSTALL_PREFIX=/emsdk/upstream/emscripten/system \ -DZ3_BUILD_LIBZ3_SHARED=OFF \ -DZ3_ENABLE_EXAMPLE_TARGETS=OFF \ -DZ3_BUILD_TEST_EXECUTABLES=OFF \ @@ -63,5 +67,5 @@ RUN set -ex; \ ./b2 toolset=emscripten link=static variant=release threading=single runtime-link=static \ --with-system --with-filesystem --with-test --with-program_options \ cxxflags="-s DISABLE_EXCEPTION_CATCHING=0 -Wno-unused-local-typedef -Wno-variadic-macros -Wno-c99-extensions -Wno-all" \ - --prefix=/emsdk/upstream/emscripten/system install; \ + --prefix=$(em-config CACHE)/sysroot/usr install; \ rm -r /usr/src/boost_1_75_0 From affeff18f5afbf4f27750179b3cb5ef07cadc0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 30 Sep 2021 20:38:28 +0200 Subject: [PATCH 0082/1748] Don't ignore output selection in assembly mode --- Changelog.md | 1 + solc/CommandLineInterface.cpp | 50 +++++++---- solc/CommandLineParser.cpp | 17 ++++ .../args | 1 + .../evm_to_wasm_output_selection_asm_only/err | 1 + .../input.yul | 4 + .../output | 2 + .../args | 1 + .../err | 1 + .../input.yul | 4 + .../output | 87 +++++++++++++++++++ .../strict_asm_output_selection_asm_only/args | 1 + .../strict_asm_output_selection_asm_only/err | 1 + .../input.yul | 4 + .../output | 12 +++ .../strict_asm_output_selection_bin_only/args | 1 + .../strict_asm_output_selection_bin_only/err | 1 + .../input.yul | 4 + .../output | 5 ++ .../args | 1 + .../err | 1 + .../input.yul | 4 + .../output | 2 + .../strict_asm_output_selection_invalid/err | 2 +- .../args | 1 + .../err | 1 + .../input.yul | 4 + .../output | 7 ++ test/solc/CommandLineParser.cpp | 8 ++ 29 files changed, 213 insertions(+), 16 deletions(-) create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_asm_only/args create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_asm_only/err create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_asm_only/input.yul create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_asm_only/output create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/args create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/err create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/input.yul create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output create mode 100644 test/cmdlineTests/strict_asm_output_selection_asm_only/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_asm_only/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_asm_only/input.yul create mode 100644 test/cmdlineTests/strict_asm_output_selection_asm_only/output create mode 100644 test/cmdlineTests/strict_asm_output_selection_bin_only/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_bin_only/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_bin_only/input.yul create mode 100644 test/cmdlineTests/strict_asm_output_selection_bin_only/output create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_only/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_only/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_only/input.yul create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_only/output create mode 100644 test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/input.yul create mode 100644 test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output diff --git a/Changelog.md b/Changelog.md index 80bd749c7e..97fd17763f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Language Features: Compiler Features: * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. + * Commandline Interface: Support ``--asm``, ``--bin``, ``--ir-optimized`` and ``--ewasm`` output selection options in assembler mode. * Commandline Interface: Use different colors when printing errors, warnings and infos. * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. * SMTChecker: Report contract invariants and reentrancy properties. This can be enabled via the CLI option ``--model-checker-invariants`` or the Standard JSON option ``settings.modelChecker.invariants``. diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 9d22799106..49aa1b87f1 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1042,34 +1042,54 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul: yul::AssemblyStack& stack = assemblyStacks[src.first]; - sout() << endl << "Pretty printed source:" << endl; - sout() << stack.print() << endl; + if (m_options.compiler.outputs.irOptimized) + { + // NOTE: This actually outputs unoptimized code when the optimizer is disabled but + // 'ir' output in StandardCompiler works the same way. + sout() << endl << "Pretty printed source:" << endl; + sout() << stack.print() << endl; + } if (_language != yul::AssemblyStack::Language::Ewasm && _targetMachine == yul::AssemblyStack::Machine::Ewasm) { stack.translate(yul::AssemblyStack::Language::Ewasm); stack.optimize(); - sout() << endl << "==========================" << endl; - sout() << endl << "Translated source:" << endl; - sout() << stack.print() << endl; + // TODO: This isn't ewasm but it's only present when we're doing Yul->EWASM translation. + // It should get its own output flag in the future. + if (m_options.compiler.outputs.ewasm) + { + sout() << endl << "==========================" << endl; + sout() << endl << "Translated source:" << endl; + sout() << stack.print() << endl; + } } yul::MachineAssemblyObject object; object = stack.assemble(_targetMachine); object.bytecode->link(m_options.linker.libraries); - sout() << endl << "Binary representation:" << endl; - if (object.bytecode) - sout() << object.bytecode->toHex() << endl; - else - serr() << "No binary representation found." << endl; + if (m_options.compiler.outputs.binary) + { + sout() << endl << "Binary representation:" << endl; + if (object.bytecode) + sout() << object.bytecode->toHex() << endl; + else + serr() << "No binary representation found." << endl; + } - sout() << endl << "Text representation:" << endl; - if (!object.assembly.empty()) - sout() << object.assembly << endl; - else - serr() << "No text representation found." << endl; + solAssert(_targetMachine == yul::AssemblyStack::Machine::Ewasm || _targetMachine == yul::AssemblyStack::Machine::EVM, ""); + if ( + (_targetMachine == yul::AssemblyStack::Machine::EVM && m_options.compiler.outputs.asm_) || + (_targetMachine == yul::AssemblyStack::Machine::Ewasm && m_options.compiler.outputs.ewasm) + ) + { + sout() << endl << "Text representation:" << endl; + if (!object.assembly.empty()) + sout() << object.assembly << endl; + else + serr() << "No text representation found." << endl; + } } return true; diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index c3448ff8fa..4bb5dfce63 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -450,6 +450,12 @@ bool CommandLineParser::parseOutputSelection() CompilerOutputs::componentMap() | ranges::views::keys | ranges::to(); + static set const assemblerModeOutputs = { + CompilerOutputs::componentName(&CompilerOutputs::asm_), + CompilerOutputs::componentName(&CompilerOutputs::binary), + CompilerOutputs::componentName(&CompilerOutputs::irOptimized), + CompilerOutputs::componentName(&CompilerOutputs::ewasm), + }; switch (_mode) { @@ -461,6 +467,7 @@ bool CommandLineParser::parseOutputSelection() case InputMode::CompilerWithASTImport: return contains(compilerModeOutputs, _outputName); case InputMode::Assembler: + return contains(assemblerModeOutputs, _outputName); case InputMode::StandardJson: case InputMode::Linker: return false; @@ -472,6 +479,16 @@ bool CommandLineParser::parseOutputSelection() for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap()) m_options.compiler.outputs.*outputComponent = (m_args.count(optionName) > 0); + if (m_options.input.mode == InputMode::Assembler && m_options.compiler.outputs == CompilerOutputs{}) + { + // In assembly mode keep the default outputs enabled for backwards-compatibility. + // TODO: Remove this (must be done in a breaking release). + m_options.compiler.outputs.asm_ = true; + m_options.compiler.outputs.binary = true; + m_options.compiler.outputs.irOptimized = true; + m_options.compiler.outputs.ewasm = true; + } + vector unsupportedOutputs; for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap()) if (m_options.compiler.outputs.*outputComponent && !outputSupported(m_options.input.mode, optionName)) diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/args b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/args new file mode 100644 index 0000000000..f390384981 --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/args @@ -0,0 +1 @@ +--assemble --optimize --yul-dialect evm --machine ewasm --asm diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/err b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/input.yul b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/input.yul new file mode 100644 index 0000000000..4fa5ef66f8 --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/output b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/output new file mode 100644 index 0000000000..d0cb60f39b --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_asm_only/output @@ -0,0 +1,2 @@ + +======= evm_to_wasm_output_selection_asm_only/input.yul (Ewasm) ======= diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/args b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/args new file mode 100644 index 0000000000..48a844213a --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/args @@ -0,0 +1 @@ +--assemble --optimize --yul-dialect evm --machine ewasm --ewasm diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/err b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/input.yul b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/input.yul new file mode 100644 index 0000000000..4fa5ef66f8 --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output new file mode 100644 index 0000000000..5f9a6c0fb2 --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output @@ -0,0 +1,87 @@ + +======= evm_to_wasm_output_selection_ewasm_only/input.yul (Ewasm) ======= + +========================== + +Translated source: +object "object" { + code { + function main() + { + let hi := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(0))), 32) + let y := i64.or(hi, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(0, 32))))) + i64.store(0:i32, y) + i64.store(i32.add(0:i32, 8:i32), y) + i64.store(i32.add(0:i32, 16:i32), y) + i64.store(i32.add(0:i32, 24:i32), y) + i64.store(32:i32, y) + i64.store(i32.add(32:i32, 8:i32), y) + i64.store(i32.add(32:i32, 16:i32), y) + let hi_1 := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(42))), 32) + i64.store(i32.add(32:i32, 24:i32), i64.or(hi_1, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(42, 32)))))) + eth.storageStore(0:i32, 32:i32) + } + function bswap16(x:i32) -> y:i32 + { + y := i32.or(i32.and(i32.shl(x, 8:i32), 0xff00:i32), i32.and(i32.shr_u(x, 8:i32), 0xff:i32)) + } + function bswap32(x:i32) -> y:i32 + { + let hi:i32 := i32.shl(bswap16(x), 16:i32) + y := i32.or(hi, bswap16(i32.shr_u(x, 16:i32))) + } + } +} + + +Text representation: +(module + (import "ethereum" "storageStore" (func $eth.storageStore (param i32 i32))) + (memory $memory (export "memory") 1) + (export "main" (func $main)) + +(func $main + (local $hi i64) + (local $y i64) + (local $hi_1 i64) + (block $label_ + (local.set $hi (i64.shl (i64.extend_i32_u (call $bswap32 (i32.wrap_i64 (i64.const 0)))) (i64.const 32))) + (local.set $y (i64.or (local.get $hi) (i64.extend_i32_u (call $bswap32 (i32.wrap_i64 (i64.shr_u (i64.const 0) (i64.const 32))))))) + (i64.store (i32.const 0) (local.get $y)) + (i64.store (i32.add (i32.const 0) (i32.const 8)) (local.get $y)) + (i64.store (i32.add (i32.const 0) (i32.const 16)) (local.get $y)) + (i64.store (i32.add (i32.const 0) (i32.const 24)) (local.get $y)) + (i64.store (i32.const 32) (local.get $y)) + (i64.store (i32.add (i32.const 32) (i32.const 8)) (local.get $y)) + (i64.store (i32.add (i32.const 32) (i32.const 16)) (local.get $y)) + (local.set $hi_1 (i64.shl (i64.extend_i32_u (call $bswap32 (i32.wrap_i64 (i64.const 42)))) (i64.const 32))) + (i64.store (i32.add (i32.const 32) (i32.const 24)) (i64.or (local.get $hi_1) (i64.extend_i32_u (call $bswap32 (i32.wrap_i64 (i64.shr_u (i64.const 42) (i64.const 32))))))) + (call $eth.storageStore (i32.const 0) (i32.const 32)) + ) +) + +(func $bswap16 + (param $x i32) + (result i32) + (local $y i32) + (block $label__1 + (local.set $y (i32.or (i32.and (i32.shl (local.get $x) (i32.const 8)) (i32.const 65280)) (i32.and (i32.shr_u (local.get $x) (i32.const 8)) (i32.const 255)))) + + ) + (local.get $y) +) + +(func $bswap32 + (param $x i32) + (result i32) + (local $y i32) + (local $hi i32) + (block $label__2 + (local.set $hi (i32.shl (call $bswap16 (local.get $x)) (i32.const 16))) + (local.set $y (i32.or (local.get $hi) (call $bswap16 (i32.shr_u (local.get $x) (i32.const 16))))) + + ) + (local.get $y) +) + +) diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/args b/test/cmdlineTests/strict_asm_output_selection_asm_only/args new file mode 100644 index 0000000000..eff0311702 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/args @@ -0,0 +1 @@ +--strict-assembly --optimize --asm diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/err b/test/cmdlineTests/strict_asm_output_selection_asm_only/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/input.yul b/test/cmdlineTests/strict_asm_output_selection_asm_only/input.yul new file mode 100644 index 0000000000..4fa5ef66f8 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/strict_asm_output_selection_asm_only/output b/test/cmdlineTests/strict_asm_output_selection_asm_only/output new file mode 100644 index 0000000000..abe2143d3f --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_asm_only/output @@ -0,0 +1,12 @@ + +======= strict_asm_output_selection_asm_only/input.yul (EVM) ======= + +Text representation: + /* "strict_asm_output_selection_asm_only/input.yul":15:17 */ + 0x2a + /* "strict_asm_output_selection_asm_only/input.yul":29:30 */ + 0x00 + /* "strict_asm_output_selection_asm_only/input.yul":22:34 */ + sstore + /* "strict_asm_output_selection_asm_only/input.yul":0:36 */ + stop diff --git a/test/cmdlineTests/strict_asm_output_selection_bin_only/args b/test/cmdlineTests/strict_asm_output_selection_bin_only/args new file mode 100644 index 0000000000..73ca2cca29 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_bin_only/args @@ -0,0 +1 @@ +--strict-assembly --optimize --bin diff --git a/test/cmdlineTests/strict_asm_output_selection_bin_only/err b/test/cmdlineTests/strict_asm_output_selection_bin_only/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_bin_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/strict_asm_output_selection_bin_only/input.yul b/test/cmdlineTests/strict_asm_output_selection_bin_only/input.yul new file mode 100644 index 0000000000..4fa5ef66f8 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_bin_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/strict_asm_output_selection_bin_only/output b/test/cmdlineTests/strict_asm_output_selection_bin_only/output new file mode 100644 index 0000000000..3ffa826b87 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_bin_only/output @@ -0,0 +1,5 @@ + +======= strict_asm_output_selection_bin_only/input.yul (EVM) ======= + +Binary representation: +602a60005500 diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_only/args b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/args new file mode 100644 index 0000000000..bb147ae337 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/args @@ -0,0 +1 @@ +--strict-assembly --optimize --ewasm diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_only/err b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_only/input.yul b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/input.yul new file mode 100644 index 0000000000..4fa5ef66f8 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_only/output b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/output new file mode 100644 index 0000000000..f90f049aaa --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_only/output @@ -0,0 +1,2 @@ + +======= strict_asm_output_selection_ewasm_only/input.yul (EVM) ======= diff --git a/test/cmdlineTests/strict_asm_output_selection_invalid/err b/test/cmdlineTests/strict_asm_output_selection_invalid/err index 736eb2c8a6..9c91044829 100644 --- a/test/cmdlineTests/strict_asm_output_selection_invalid/err +++ b/test/cmdlineTests/strict_asm_output_selection_invalid/err @@ -1 +1 @@ -The following outputs are not supported in assembler mode: --abi, --asm, --asm-json, --bin, --bin-runtime, --devdoc, --ewasm, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc. +The following outputs are not supported in assembler mode: --abi, --asm-json, --bin-runtime, --devdoc, --hashes, --ir, --metadata, --opcodes, --storage-layout, --userdoc. diff --git a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/args b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/args new file mode 100644 index 0000000000..90b16d1f0e --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/args @@ -0,0 +1 @@ +--strict-assembly --optimize --ir-optimized diff --git a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/err b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/input.yul b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/input.yul new file mode 100644 index 0000000000..4fa5ef66f8 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output new file mode 100644 index 0000000000..1fa4b72c7e --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output @@ -0,0 +1,7 @@ + +======= strict_asm_output_selection_ir_optimized_only/input.yul (EVM) ======= + +Pretty printed source: +object "object" { + code { { sstore(0, 42) } } +} diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index a9ba08d817..dd5696c688 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -297,6 +297,10 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) "underflow," "divByZero", "--model-checker-timeout=5", // Ignored in assembly mode + "--asm", + "--bin", + "--ir-optimized", + "--ewasm", }; commandLine += assemblyOptions; if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm) @@ -333,6 +337,10 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) }; expectedOptions.formatting.coloredOutput = false; expectedOptions.formatting.withErrorIds = true; + expectedOptions.compiler.outputs.asm_ = true; + expectedOptions.compiler.outputs.binary = true; + expectedOptions.compiler.outputs.irOptimized = true; + expectedOptions.compiler.outputs.ewasm = true; if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm) { expectedOptions.optimizer.enabled = true; From 1a19d9a5cf75b3677baf7c5a85cd5e9500d8a4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 3 Nov 2021 17:01:48 +0100 Subject: [PATCH 0083/1748] New CLI output in assembly mode: `--ewasm-ir` --- Changelog.md | 2 +- solc/CommandLineInterface.cpp | 4 +-- solc/CommandLineParser.cpp | 11 ++++-- solc/CommandLineParser.h | 2 ++ .../args | 1 + .../err | 1 + .../input.yul | 4 +++ .../output | 34 +++++++++++++++++++ .../output | 33 ------------------ .../output_selection_ewasm_ir_only/args | 1 + .../output_selection_ewasm_ir_only/err | 1 + .../output_selection_ewasm_ir_only/exit | 1 + .../output_selection_ewasm_ir_only/input.sol | 4 +++ .../args | 2 +- .../standard_cli_output_selection_invalid/err | 2 +- .../args | 1 + .../err | 1 + .../input.yul | 4 +++ .../output | 2 ++ test/solc/CommandLineParser.cpp | 4 +++ 20 files changed, 73 insertions(+), 42 deletions(-) create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/args create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/err create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/input.yul create mode 100644 test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/output create mode 100644 test/cmdlineTests/output_selection_ewasm_ir_only/args create mode 100644 test/cmdlineTests/output_selection_ewasm_ir_only/err create mode 100644 test/cmdlineTests/output_selection_ewasm_ir_only/exit create mode 100644 test/cmdlineTests/output_selection_ewasm_ir_only/input.sol create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/args create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/err create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/input.yul create mode 100644 test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/output diff --git a/Changelog.md b/Changelog.md index 97fd17763f..3f7ea97c56 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,7 +7,7 @@ Language Features: Compiler Features: * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. - * Commandline Interface: Support ``--asm``, ``--bin``, ``--ir-optimized`` and ``--ewasm`` output selection options in assembler mode. + * Commandline Interface: Support ``--asm``, ``--bin``, ``--ir-optimized``, ``--ewasm`` and ``--ewasm-ir`` output selection options in assembler mode. * Commandline Interface: Use different colors when printing errors, warnings and infos. * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. * SMTChecker: Report contract invariants and reentrancy properties. This can be enabled via the CLI option ``--model-checker-invariants`` or the Standard JSON option ``settings.modelChecker.invariants``. diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 49aa1b87f1..1d069f9251 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1055,9 +1055,7 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul: stack.translate(yul::AssemblyStack::Language::Ewasm); stack.optimize(); - // TODO: This isn't ewasm but it's only present when we're doing Yul->EWASM translation. - // It should get its own output flag in the future. - if (m_options.compiler.outputs.ewasm) + if (m_options.compiler.outputs.ewasmIR) { sout() << endl << "==========================" << endl; sout() << endl << "Translated source:" << endl; diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 4bb5dfce63..9356c96625 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -446,15 +446,17 @@ bool CommandLineParser::parseOutputSelection() { static auto outputSupported = [](InputMode _mode, string_view _outputName) { - static set const compilerModeOutputs = + static set const compilerModeOutputs = ( CompilerOutputs::componentMap() | ranges::views::keys | - ranges::to(); + ranges::to() + ) - set{CompilerOutputs::componentName(&CompilerOutputs::ewasmIR)}; static set const assemblerModeOutputs = { CompilerOutputs::componentName(&CompilerOutputs::asm_), CompilerOutputs::componentName(&CompilerOutputs::binary), CompilerOutputs::componentName(&CompilerOutputs::irOptimized), CompilerOutputs::componentName(&CompilerOutputs::ewasm), + CompilerOutputs::componentName(&CompilerOutputs::ewasmIR), }; switch (_mode) @@ -487,6 +489,7 @@ bool CommandLineParser::parseOutputSelection() m_options.compiler.outputs.binary = true; m_options.compiler.outputs.irOptimized = true; m_options.compiler.outputs.ewasm = true; + m_options.compiler.outputs.ewasmIR = true; } vector unsupportedOutputs; @@ -709,6 +712,7 @@ General Information)").c_str(), (CompilerOutputs::componentName(&CompilerOutputs::ir).c_str(), "Intermediate Representation (IR) of all contracts (EXPERIMENTAL).") (CompilerOutputs::componentName(&CompilerOutputs::irOptimized).c_str(), "Optimized intermediate Representation (IR) of all contracts (EXPERIMENTAL).") (CompilerOutputs::componentName(&CompilerOutputs::ewasm).c_str(), "Ewasm text representation of all contracts (EXPERIMENTAL).") + (CompilerOutputs::componentName(&CompilerOutputs::ewasmIR).c_str(), "Intermediate representation (IR) converted to a form that can be translated directly into Ewasm text representation (EXPERIMENTAL).") (CompilerOutputs::componentName(&CompilerOutputs::signatureHashes).c_str(), "Function signature hashes of the contracts.") (CompilerOutputs::componentName(&CompilerOutputs::natspecUser).c_str(), "Natspec user documentation of all contracts.") (CompilerOutputs::componentName(&CompilerOutputs::natspecDev).c_str(), "Natspec developer documentation of all contracts.") @@ -923,11 +927,12 @@ bool CommandLineParser::processArgs() if (!checkMutuallyExclusive({g_strColor, g_strNoColor})) return false; - array const conflictingWithStopAfter{ + array const conflictingWithStopAfter{ CompilerOutputs::componentName(&CompilerOutputs::binary), CompilerOutputs::componentName(&CompilerOutputs::ir), CompilerOutputs::componentName(&CompilerOutputs::irOptimized), CompilerOutputs::componentName(&CompilerOutputs::ewasm), + CompilerOutputs::componentName(&CompilerOutputs::ewasmIR), g_strGas, CompilerOutputs::componentName(&CompilerOutputs::asm_), CompilerOutputs::componentName(&CompilerOutputs::asmJson), diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index 27a64c7b94..a1d13c6907 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -78,6 +78,7 @@ struct CompilerOutputs {"ir", &CompilerOutputs::ir}, {"ir-optimized", &CompilerOutputs::irOptimized}, {"ewasm", &CompilerOutputs::ewasm}, + {"ewasm-ir", &CompilerOutputs::ewasmIR}, {"hashes", &CompilerOutputs::signatureHashes}, {"userdoc", &CompilerOutputs::natspecUser}, {"devdoc", &CompilerOutputs::natspecDev}, @@ -97,6 +98,7 @@ struct CompilerOutputs bool ir = false; bool irOptimized = false; bool ewasm = false; + bool ewasmIR = false; bool signatureHashes = false; bool natspecUser = false; bool natspecDev = false; diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/args b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/args new file mode 100644 index 0000000000..7c6526b562 --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/args @@ -0,0 +1 @@ +--assemble --optimize --yul-dialect evm --machine ewasm --ewasm-ir diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/err b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/input.yul b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/input.yul new file mode 100644 index 0000000000..4fa5ef66f8 --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/output b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/output new file mode 100644 index 0000000000..3124db17da --- /dev/null +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_ir_only/output @@ -0,0 +1,34 @@ + +======= evm_to_wasm_output_selection_ewasm_ir_only/input.yul (Ewasm) ======= + +========================== + +Translated source: +object "object" { + code { + function main() + { + let hi := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(0))), 32) + let y := i64.or(hi, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(0, 32))))) + i64.store(0:i32, y) + i64.store(i32.add(0:i32, 8:i32), y) + i64.store(i32.add(0:i32, 16:i32), y) + i64.store(i32.add(0:i32, 24:i32), y) + i64.store(32:i32, y) + i64.store(i32.add(32:i32, 8:i32), y) + i64.store(i32.add(32:i32, 16:i32), y) + let hi_1 := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(42))), 32) + i64.store(i32.add(32:i32, 24:i32), i64.or(hi_1, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(42, 32)))))) + eth.storageStore(0:i32, 32:i32) + } + function bswap16(x:i32) -> y:i32 + { + y := i32.or(i32.and(i32.shl(x, 8:i32), 0xff00:i32), i32.and(i32.shr_u(x, 8:i32), 0xff:i32)) + } + function bswap32(x:i32) -> y:i32 + { + let hi:i32 := i32.shl(bswap16(x), 16:i32) + y := i32.or(hi, bswap16(i32.shr_u(x, 16:i32))) + } + } +} diff --git a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output index 5f9a6c0fb2..e8b3062605 100644 --- a/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output +++ b/test/cmdlineTests/evm_to_wasm_output_selection_ewasm_only/output @@ -1,39 +1,6 @@ ======= evm_to_wasm_output_selection_ewasm_only/input.yul (Ewasm) ======= -========================== - -Translated source: -object "object" { - code { - function main() - { - let hi := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(0))), 32) - let y := i64.or(hi, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(0, 32))))) - i64.store(0:i32, y) - i64.store(i32.add(0:i32, 8:i32), y) - i64.store(i32.add(0:i32, 16:i32), y) - i64.store(i32.add(0:i32, 24:i32), y) - i64.store(32:i32, y) - i64.store(i32.add(32:i32, 8:i32), y) - i64.store(i32.add(32:i32, 16:i32), y) - let hi_1 := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(42))), 32) - i64.store(i32.add(32:i32, 24:i32), i64.or(hi_1, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(42, 32)))))) - eth.storageStore(0:i32, 32:i32) - } - function bswap16(x:i32) -> y:i32 - { - y := i32.or(i32.and(i32.shl(x, 8:i32), 0xff00:i32), i32.and(i32.shr_u(x, 8:i32), 0xff:i32)) - } - function bswap32(x:i32) -> y:i32 - { - let hi:i32 := i32.shl(bswap16(x), 16:i32) - y := i32.or(hi, bswap16(i32.shr_u(x, 16:i32))) - } - } -} - - Text representation: (module (import "ethereum" "storageStore" (func $eth.storageStore (param i32 i32))) diff --git a/test/cmdlineTests/output_selection_ewasm_ir_only/args b/test/cmdlineTests/output_selection_ewasm_ir_only/args new file mode 100644 index 0000000000..bccff6085e --- /dev/null +++ b/test/cmdlineTests/output_selection_ewasm_ir_only/args @@ -0,0 +1 @@ +--optimize --ewasm-ir diff --git a/test/cmdlineTests/output_selection_ewasm_ir_only/err b/test/cmdlineTests/output_selection_ewasm_ir_only/err new file mode 100644 index 0000000000..52dd265b5d --- /dev/null +++ b/test/cmdlineTests/output_selection_ewasm_ir_only/err @@ -0,0 +1 @@ +The following outputs are not supported in compiler mode: --ewasm-ir. diff --git a/test/cmdlineTests/output_selection_ewasm_ir_only/exit b/test/cmdlineTests/output_selection_ewasm_ir_only/exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/cmdlineTests/output_selection_ewasm_ir_only/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/output_selection_ewasm_ir_only/input.sol b/test/cmdlineTests/output_selection_ewasm_ir_only/input.sol new file mode 100644 index 0000000000..9755e16e71 --- /dev/null +++ b/test/cmdlineTests/output_selection_ewasm_ir_only/input.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity *; + +contract C {} diff --git a/test/cmdlineTests/standard_cli_output_selection_invalid/args b/test/cmdlineTests/standard_cli_output_selection_invalid/args index f2deb3847f..538c870972 100644 --- a/test/cmdlineTests/standard_cli_output_selection_invalid/args +++ b/test/cmdlineTests/standard_cli_output_selection_invalid/args @@ -1 +1 @@ ---ast-compact-json --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --hashes --userdoc --devdoc --metadata --storage-layout +--ast-compact-json --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --ewasm --ewasm-ir --hashes --userdoc --devdoc --metadata --storage-layout diff --git a/test/cmdlineTests/standard_cli_output_selection_invalid/err b/test/cmdlineTests/standard_cli_output_selection_invalid/err index d6ed4d572c..e9d24e61d4 100644 --- a/test/cmdlineTests/standard_cli_output_selection_invalid/err +++ b/test/cmdlineTests/standard_cli_output_selection_invalid/err @@ -1 +1 @@ -The following outputs are not supported in standard JSON mode: --abi, --asm, --asm-json, --ast-compact-json, --bin, --bin-runtime, --devdoc, --ewasm, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc. +The following outputs are not supported in standard JSON mode: --abi, --asm, --asm-json, --ast-compact-json, --bin, --bin-runtime, --devdoc, --ewasm, --ewasm-ir, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc. diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/args b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/args new file mode 100644 index 0000000000..647c63654c --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/args @@ -0,0 +1 @@ +--strict-assembly --optimize --ewasm-ir diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/err b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/input.yul b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/input.yul new file mode 100644 index 0000000000..4fa5ef66f8 --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/input.yul @@ -0,0 +1,4 @@ +{ + let x := 42 + sstore(0, x) +} diff --git a/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/output b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/output new file mode 100644 index 0000000000..8026a6e83e --- /dev/null +++ b/test/cmdlineTests/strict_asm_output_selection_ewasm_ir_only/output @@ -0,0 +1,2 @@ + +======= strict_asm_output_selection_ewasm_ir_only/input.yul (EVM) ======= diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index dd5696c688..23ea1efb16 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -198,7 +198,9 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, }; + expectedOptions.compiler.outputs.ewasmIR = false; expectedOptions.compiler.estimateGas = true; expectedOptions.compiler.combinedJsonRequests = { true, true, true, true, true, @@ -301,6 +303,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) "--bin", "--ir-optimized", "--ewasm", + "--ewasm-ir", }; commandLine += assemblyOptions; if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm) @@ -341,6 +344,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) expectedOptions.compiler.outputs.binary = true; expectedOptions.compiler.outputs.irOptimized = true; expectedOptions.compiler.outputs.ewasm = true; + expectedOptions.compiler.outputs.ewasmIR = true; if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm) { expectedOptions.optimizer.enabled = true; From a7688a0eafcbc528f4a9d66e497a50e3712c4ca0 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 4 Nov 2021 19:24:12 +0100 Subject: [PATCH 0084/1748] Update emscripten to version 2.0.33. --- .circleci/config.yml | 4 ++-- Changelog.md | 1 + scripts/build_emscripten.sh | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e2ba6e2d09..9e5862cab0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -21,8 +21,8 @@ parameters: default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c26a7ffc9fc243a4ec3105b9dc1edcdd964ad0e9665c83172b7ebda74bbf3021" emscripten-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:emscripten-6 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:092da5817bc032c91a806b4f73db2a1a31e5cc4c066d94d43eedd9f365df7154" + # solbuildpackpusher/solidity-buildpack-deps:emscripten-7 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:9ffcd0944433fe100e9433f2aa9ba5c21e096e758ad8a05a4a76feaed3d1f463" evm-version: type: string default: london diff --git a/Changelog.md b/Changelog.md index 80bd749c7e..56a30bdaef 100644 --- a/Changelog.md +++ b/Changelog.md @@ -34,6 +34,7 @@ Bugfixes: Build System: * Pass linker-only emscripten options only when linking. * Remove obsolete compatibility workaround for emscripten builds. + * Update emscripten to version 2.0.33. Important Bugfixes in Experimental Features: diff --git a/scripts/build_emscripten.sh b/scripts/build_emscripten.sh index 667d63708d..7b8510026c 100755 --- a/scripts/build_emscripten.sh +++ b/scripts/build_emscripten.sh @@ -34,7 +34,7 @@ else BUILD_DIR="$1" fi -# solbuildpackpusher/solidity-buildpack-deps:emscripten-6 +# solbuildpackpusher/solidity-buildpack-deps:emscripten-7 docker run -v "$(pwd):/root/project" -w /root/project \ - solbuildpackpusher/solidity-buildpack-deps@sha256:092da5817bc032c91a806b4f73db2a1a31e5cc4c066d94d43eedd9f365df7154 \ + solbuildpackpusher/solidity-buildpack-deps@sha256:9ffcd0944433fe100e9433f2aa9ba5c21e096e758ad8a05a4a76feaed3d1f463 \ ./scripts/ci/build_emscripten.sh "$BUILD_DIR" From b4f98b41bc9424be1d2cb659deaa9255b51cf3f2 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 5 Nov 2021 13:03:13 +0100 Subject: [PATCH 0085/1748] Minor fix to forEach on Yul AST nodes. --- libyul/optimiser/ASTWalker.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libyul/optimiser/ASTWalker.h b/libyul/optimiser/ASTWalker.h index cd98a90cad..b937f7eae4 100644 --- a/libyul/optimiser/ASTWalker.h +++ b/libyul/optimiser/ASTWalker.h @@ -111,8 +111,7 @@ template < > struct ForEach: Base { - template - ForEach(Callable&& _visitor): visitor(std::forward(_visitor)) {} + ForEach(Visitor& _visitor): visitor(_visitor) {} using Base::operator(); void operator()(Node& _node) override @@ -121,7 +120,7 @@ struct ForEach: Base Base::operator()(_node); } - Visitor visitor; + Visitor& visitor; }; } @@ -130,7 +129,7 @@ struct ForEach: Base template void forEach(Entry&& _entry, Visitor&& _visitor) { - detail::ForEach>{std::forward(_visitor)}(std::forward(_entry)); + detail::ForEach{_visitor}(_entry); } } From 83308184f20f811d438df1bddc3921e7982279bd Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 5 Nov 2021 17:46:32 +0100 Subject: [PATCH 0086/1748] Remove outdated install_deps scripts. --- scripts/install_deps.bat | 61 ---------------------- scripts/install_deps.cmake | 99 ------------------------------------ scripts/install_static_z3.sh | 11 ---- 3 files changed, 171 deletions(-) delete mode 100644 scripts/install_deps.bat delete mode 100644 scripts/install_deps.cmake delete mode 100644 scripts/install_static_z3.sh diff --git a/scripts/install_deps.bat b/scripts/install_deps.bat deleted file mode 100644 index 61f7022a5e..0000000000 --- a/scripts/install_deps.bat +++ /dev/null @@ -1,61 +0,0 @@ -@ECHO OFF - -REM --------------------------------------------------------------------------- -REM Batch file for installing pre-requisite packages for solidity on -REM Windows platforms. That is implemented using CMake targets which -REM extract pre-built ZIPs hosted on GitHub into "deps\install_deps". -REM -REM See https://github.com/ethereum/cpp-dependencies -REM -REM The CMake files then point into that directory as an alternative -REM to the Homebrew, PPA or other global package server locations -REM available on Linux and UNIX platforms. -REM -REM The lack of a standard C++ packaging system for Windows is problematic -REM for us, and we have considered various options for improving the -REM situation, such as the following: -REM -REM See "Windows - Add support for Chocolatey packages" -REM https://github.com/ethereum/webthree-umbrella/issues/345 -REM -REM See "Windows - Try to use NuGet C++ packages" -REM https://github.com/ethereum/webthree-umbrella/issues/509 -REM -REM See "CM - Can we switch to NuGet delivery for our external dependencies" -REM https://github.com/ethereum/webthree-umbrella/issues/376 -REM -REM Another possible option, which would benefit build robustness on -REM multiple platforms, not just Windows, is to add dependencies as -REM git-submodules (or downloading on demand) so that we aren'targets -REM depend on platform-specific packaging systems at all. We have -REM already done just that for LLVM within evmjit. The downside of -REM that approach is that those dependencies then need to be -REM built-from-source, which adds time to the build process. It -REM gives us an unbeatable degree of control, though, because we -REM then perfectly control versioning and build flags for the binaries -REM for those packages. -REM -REM The documentation for solidity is hosted at: -REM -REM https://docs.soliditylang.org -REM -REM --------------------------------------------------------------------------- -REM This file is part of solidity. -REM -REM solidity is free software: you can redistribute it and/or modify -REM it under the terms of the GNU General Public License as published by -REM the Free Software Foundation, either version 3 of the License, or -REM (at your option) any later version. -REM -REM solidity is distributed in the hope that it will be useful, -REM but WITHOUT ANY WARRANTY; without even the implied warranty of -REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -REM GNU General Public License for more details. -REM -REM You should have received a copy of the GNU General Public License -REM along with solidity. If not, see -REM -REM Copyright (c) 2016 solidity contributors. -REM --------------------------------------------------------------------------- - -cmake -P scripts\install_deps.cmake diff --git a/scripts/install_deps.cmake b/scripts/install_deps.cmake deleted file mode 100644 index d90d4ec32b..0000000000 --- a/scripts/install_deps.cmake +++ /dev/null @@ -1,99 +0,0 @@ -get_filename_component(ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../deps" ABSOLUTE) - -set(CACHE_DIR "${ROOT_DIR}/cache") -set(PACKAGES_DIR "${ROOT_DIR}/packages") - -function(download URL DST_FILE STATUS) - set(TMP_FILE "${DST_FILE}.part") - - get_filename_component(FILE_NAME ${DST_FILE} NAME) - if (NOT EXISTS ${DST_FILE}) - message("Downloading ${FILE_NAME}") - file(DOWNLOAD ${URL} ${TMP_FILE} SHOW_PROGRESS STATUS DOWNLOAD_STATUS) - list(GET DOWNLOAD_STATUS 0 STATUS_CODE) - if (STATUS_CODE EQUAL 0) - file(RENAME ${TMP_FILE} ${DST_FILE}) - else() - file(REMOVE ${TMP_FILE}) - list(GET DOWNLOAD_STATUS 1 ERROR_MSG) - - message("ERROR! Downloading '${FILE_NAME}' failed.") - message(STATUS "URL: ${URL}") - message(STATUS "Error: ${STATUS_CODE} ${ERROR_MSG}") - set(STATUS FALSE PARENT_SCOPE) - return() - endif() - else() - message("Using cached ${FILE_NAME}") - endif() - set(STATUS TRUE PARENT_SCOPE) -endfunction(download) - -function(download_and_unpack PACKAGE_URL DST_DIR) - get_filename_component(FILE_NAME ${PACKAGE_URL} NAME) - - set(DST_FILE "${CACHE_DIR}/${FILE_NAME}") - set(TMP_FILE "${DST_FILE}.part") - - file(MAKE_DIRECTORY ${CACHE_DIR}) - file(MAKE_DIRECTORY ${DST_DIR}) - - download(${PACKAGE_URL} ${DST_FILE} STATUS) - - if (STATUS) - message("Unpacking ${FILE_NAME} to ${DST_DIR}") - execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${DST_FILE} - WORKING_DIRECTORY ${DST_DIR}) - endif() -endfunction(download_and_unpack) - -# Packs installed package binaries and headers into an archive. -function(create_package NAME DIR) - message("Creating package ${NAME}") - file(MAKE_DIRECTORY ${PACKAGES_DIR}) - - # To create an archive without addicional top level directory - # (like package-X.Y.Z) we need to know all top level files/dirs. - # Usually it is just "win64" dir. - file(GLOB TOP_FILES RELATIVE ${DIR} "${DIR}/*") - - set(PACKAGE_FILE "${PACKAGES_DIR}/${NAME}.tar.gz") - execute_process(COMMAND ${CMAKE_COMMAND} -E - tar -czf ${PACKAGE_FILE} ${TOP_FILES} - WORKING_DIRECTORY ${DIR}) -endfunction(create_package) - -# Downloads the source code of the package and unpacks it to dedicated 'src' -# dir. Also creates 'build' and 'install' dir to be used by a build script. -function(prepare_package_source NAME VERSION URL) - set(PACKAGE_NAME "${NAME}-${VERSION}") - - set(PACKAGE_DIR "${CACHE_DIR}/${PACKAGE_NAME}") - set(SOURCE_DIR "${PACKAGE_DIR}/src") - set(BUILD_DIR "${PACKAGE_DIR}/build") - set(INSTALL_DIR "${PACKAGE_DIR}/install") - - if (NOT EXISTS ${SOURCE_DIR}) - download_and_unpack(${URL} ${PACKAGE_DIR} STATUS) - file(GLOB ORIG_SOURCE_DIR_NAME "${PACKAGE_DIR}/*") - file(RENAME ${ORIG_SOURCE_DIR_NAME} ${SOURCE_DIR}) - endif() - - file(MAKE_DIRECTORY ${BUILD_DIR}) - file(MAKE_DIRECTORY ${INSTALL_DIR}) - - # Export names and dirs to be used by a package-specific build script. - set(PACKAGE_NAME ${PACKAGE_NAME} PARENT_SCOPE) - set(SOURCE_DIR ${SOURCE_DIR} PARENT_SCOPE) - set(BUILD_DIR ${BUILD_DIR} PARENT_SCOPE) - set(INSTALL_DIR ${INSTALL_DIR} PARENT_SCOPE) -endfunction() - -set(INSTALL_DIR "${ROOT_DIR}/install") -set(SERVER "https://github.com/ethereum/cpp-dependencies/releases/download/vs2017/") - -function(download_and_install PACKAGE_NAME) - download_and_unpack("${SERVER}${PACKAGE_NAME}.tar.gz" ${INSTALL_DIR}) -endfunction(download_and_install) - -download_and_install("boost-1.67.0") diff --git a/scripts/install_static_z3.sh b/scripts/install_static_z3.sh deleted file mode 100644 index 304ef410cf..0000000000 --- a/scripts/install_static_z3.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -set -eu - -git clone --depth 1 --branch z3-4.8.7 https://github.com/Z3Prover/z3.git -cd z3 -mkdir build -cd build -LDFLAGS="-static" cmake -DZ3_BUILD_LIBZ3_SHARED=OFF .. -make -j 4 -make install \ No newline at end of file From 063d00adc88c397230f31ff1803a1502b78af452 Mon Sep 17 00:00:00 2001 From: Shivam Rajput <75530356+phyBrackets@users.noreply.github.com> Date: Sun, 7 Nov 2021 10:41:48 +0530 Subject: [PATCH 0087/1748] 0.y.z makes more sense than 0.x for the current version. --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index a7bfbbe448..476cd86117 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,7 +21,7 @@ version of Solidity. Apart from exceptional cases, only the latest version recei `security fixes `_. Furthermore, breaking changes as well as new features are introduced regularly. We currently use -a 0.x version number `to indicate this fast pace of change `_. +a 0.y.z version number `to indicate this fast pace of change `_. .. warning:: From c6775bc01f59c04796bf4d15db9ec2ccd72710a2 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sun, 7 Nov 2021 21:27:56 +0000 Subject: [PATCH 0088/1748] Include picosha2 in the license header --- cmake/templates/license.h.in | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/cmake/templates/license.h.in b/cmake/templates/license.h.in index 65276d8b4c..6cdd2bb8a8 100644 --- a/cmake/templates/license.h.in +++ b/cmake/templates/license.h.in @@ -6,9 +6,34 @@ static std::string const otherLicenses{R"(Most of the code is licensed under GPL parts are as follows: libkeccak-tiny: + The file libsolutil/Keccak256.cpp incorporates libkeccak-tiny. + A single-file implementation of SHA-3 and SHAKE implemented by David Leon Gil License: CC0, attribution kindly requested. Blame taken too, but not liability. +picosha2: + The file libsolutil/picosha2.h is imported. + + Copyright (C) 2017 okdshin + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + jsoncpp: The JsonCpp library's source code, including accompanying documentation, tests and demonstration applications, are licensed under the following From be552683c93ca8830a793ccd7805c7ad2e370228 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 8 Nov 2021 10:58:28 +0100 Subject: [PATCH 0089/1748] Remove incorrect outer block from for loop init rewriter documentation. --- docs/internals/optimizer.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index 93179c0418..28c342902d 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -429,11 +429,9 @@ is transformed to .. code-block:: text - { - Init... - for {} C { Post... } { - Body... - } + Init... + for {} C { Post... } { + Body... } This eases the rest of the optimization process because we can ignore From aa4d3cabf1e698bf871877d66d88d4bb48139611 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 8 Nov 2021 13:22:23 +0100 Subject: [PATCH 0090/1748] Clarify ``pure``. --- docs/contracts/functions.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/contracts/functions.rst b/docs/contracts/functions.rst index 7d1ce72565..ff49e4f281 100644 --- a/docs/contracts/functions.rst +++ b/docs/contracts/functions.rst @@ -222,6 +222,9 @@ Pure Functions -------------- Functions can be declared ``pure`` in which case they promise not to read from or modify the state. +In particular, it should be possible to evaluate a ``pure`` function at compile-time given +only its inputs and ``msg.data``, but without any knowledge of the current blockchain state. +This means that reading from ``immutable`` variables can be a non-pure operation. .. note:: If the compiler's EVM target is Byzantium or newer (default) the opcode ``STATICCALL`` is used, From a1aa9d2d90f2f7e7390408e9005d62c7159d4bd4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 27 Oct 2021 17:26:44 +0200 Subject: [PATCH 0091/1748] Skip extcodesize check if return data is expected. --- Changelog.md | 1 + libsolidity/codegen/ExpressionCompiler.cpp | 18 +- .../codegen/ir/IRGeneratorForStatements.cpp | 20 +- .../output.json | 190 ++++++++++++++++++ .../output.json | 32 +-- .../abi_encode_calldata_slice.sol | 4 +- .../struct/struct_storage_ptr.sol | 2 +- .../abi_encode_calldata_slice.sol | 4 +- ...2_in_function_inherited_in_v1_contract.sol | 2 +- ...ode_v2_in_modifier_used_in_v1_contract.sol | 2 +- .../abiEncoderV2/calldata_array.sol | 2 +- .../arithmetics/check_var_init.sol | 2 +- .../array/fixed_arrays_as_return_type.sol | 2 +- .../array/function_array_cross_calls.sol | 2 +- .../semanticTests/array/reusing_memory.sol | 2 +- .../constructor/arrays_in_constructors.sol | 2 +- .../bytes_in_constructors_packer.sol | 2 +- .../constructor_function_complex.sol | 2 +- .../freeFunctions/new_operator.sol | 2 +- .../creation_function_call_no_args.sol | 2 +- .../functionCall/failed_create.sol | 4 +- .../functionTypes/store_function.sol | 2 +- .../immutable/multi_creation.sol | 2 +- .../address_overload_resolution.sol | 4 +- ...d_function_calldata_calldata_interface.sol | 2 +- ...ted_function_calldata_memory_interface.sol | 2 +- .../inheritance/member_notation_ctor.sol | 4 +- .../interface_inheritance_conversions.sol | 4 +- .../salted_create_with_value.sol | 2 +- .../semanticTests/smoke/alignment.sol | 2 +- .../various/code_access_content.sol | 2 +- .../various/code_access_create.sol | 2 +- .../various/external_types_in_calls.sol | 2 +- .../skip_dynamic_types_for_structs.sol | 2 +- .../various/staticcall_for_view_and_pure.sol | 6 +- 35 files changed, 270 insertions(+), 67 deletions(-) diff --git a/Changelog.md b/Changelog.md index f020044370..54088143b4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Language Features: Compiler Features: + * Code Generator: Skip existence check for external contract if return data is expected. In this case, the ABI decoder will revert if the contract does not exist. * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. * Commandline Interface: Use different colors when printing errors, warnings and infos. diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 731cf1a41a..07d37c4c58 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -2630,9 +2630,21 @@ void ExpressionCompiler::appendExternalFunctionCall( // Check the target contract exists (has code) for non-low-level calls. if (funKind == FunctionType::Kind::External || funKind == FunctionType::Kind::DelegateCall) { - m_context << Instruction::DUP1 << Instruction::EXTCODESIZE << Instruction::ISZERO; - m_context.appendConditionalRevert(false, "Target contract does not contain code"); - existenceChecked = true; + size_t encodedHeadSize = 0; + for (auto const& t: returnTypes) + encodedHeadSize += t->decodingType()->calldataHeadSize(); + // We do not need to check extcodesize if we expect return data, since if there is no + // code, the call will return empty data and the ABI decoder will revert. + if ( + encodedHeadSize == 0 || + !haveReturndatacopy || + m_context.revertStrings() >= RevertStrings::Debug + ) + { + m_context << Instruction::DUP1 << Instruction::EXTCODESIZE << Instruction::ISZERO; + m_context.appendConditionalRevert(false, "Target contract does not contain code"); + existenceChecked = true; + } } if (_functionType.gasSet()) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 6d7ee86f53..85b21bbdcd 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2451,8 +2451,10 @@ void IRGeneratorForStatements::appendExternalFunctionCall( appendCode() << "mstore(add(" << m_utils.allocateUnboundedFunction() << "() , " << to_string(returnInfo.estimatedReturnSize) << "), 0)\n"; } - Whiskers templ(R"(if iszero(extcodesize(
)) { () } - + Whiskers templ(R"( + + if iszero(extcodesize(
)) { () } + // storage for arguments and returned data let := () mstore(, ()) @@ -2477,6 +2479,18 @@ void IRGeneratorForStatements::appendExternalFunctionCall( } )"); templ("revertNoCode", m_utils.revertReasonIfDebugFunction("Target contract does not contain code")); + + // We do not need to check extcodesize if we expect return data: If there is no + // code, the call will return empty data and the ABI decoder will revert. + size_t encodedHeadSize = 0; + for (auto const& t: returnInfo.returnTypes) + encodedHeadSize += t->decodingType()->calldataHeadSize(); + bool const checkExtcodesize = + encodedHeadSize == 0 || + !m_context.evmVersion().supportsReturndata() || + m_context.revertStrings() >= RevertStrings::Debug; + templ("checkExtcodesize", checkExtcodesize); + templ("pos", m_context.newYulVariable()); templ("end", m_context.newYulVariable()); if (_functionCall.annotation().tryCall) @@ -2532,6 +2546,8 @@ void IRGeneratorForStatements::appendExternalFunctionCall( u256 gasNeededByCaller = evmasm::GasCosts::callGas(m_context.evmVersion()) + 10; if (funType.valueSet()) gasNeededByCaller += evmasm::GasCosts::callValueTransferGas; + if (!checkExtcodesize) + gasNeededByCaller += evmasm::GasCosts::callNewAccountGas; // we never know templ("gas", "sub(gas(), " + formatNumber(gasNeededByCaller) + ")"); } // Order is important here, STATICCALL might overlap with DELEGATECALL. diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json index 0c529109ae..773637b321 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json @@ -289,6 +289,19 @@ sub_0: assembly { address /* \"C\":403:411 this.f() */ extcodesize + tag_40 + jumpi + /* \"C\":79:428 contract C... */ + dup2 + dup3 + revert + /* \"C\":403:411 this.f() */ + tag_40: + /* \"C\":79:428 contract C... */ + /* \"C\":403:407 this */ + address + /* \"C\":403:411 this.f() */ + extcodesize iszero tag_43 jumpi @@ -316,6 +329,8 @@ sub_0: assembly { tag_45 jumpi dup1 + tag_41 + tag_40 swap3 tag_47 jumpi @@ -344,12 +359,22 @@ sub_0: assembly { swap1 jump\t// out /* \"C\":403:411 this.f() */ + tag_41: + tag_40: tag_47: /* \"C\":79:428 contract C... */ swap1 swap2 pop /* \"C\":403:411 this.f() */ + dup2 + iszero + tag_42 + jumpi + dup2 + iszero + tag_41 + jumpi returndatasize /* \"C\":79:428 contract C... */ 0x1f @@ -366,6 +391,10 @@ sub_0: assembly { dup4 lt or + iszero + tag_43 + iszero + tag_42 tag_51 jumpi pop @@ -379,26 +408,56 @@ sub_0: assembly { /* \"C\":392:422 stateVar + this.f() + immutVar */ tag_50 /* \"C\":79:428 contract C... */ + mstore + 0x24 + dup7 + revert + tag_43: + mstore + 0x24 + dup7 + revert + tag_42: swap5 0x40 mstore /* \"C\":403:411 this.f() */ + tag_44 + tag_43 returndatasize dup2 add swap1 tag_7 jump\t// in + tag_44: + swap1 + tag_43: + swap1 tag_53: swap2 dup2 swap4 pop + tag_42: + /* \"C\":392:411 stateVar + this.f() */ + tag_45 + tag_41: + /* \"C\":392:411 stateVar + this.f() */ + tag_44 jump(tag_48) /* \"C\":79:428 contract C... */ tag_51: shl(0xe0, 0x4e487b71) dup2 + dup6 + tag_5 + jump\t// in + tag_45: + dup6 + tag_5 + jump\t// in + tag_44: mstore 0x41 /* \"C\":403:411 this.f() */ @@ -422,12 +481,30 @@ sub_0: assembly { pop pop pop + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_46 + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_45 + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ pop mload(0x40) swap1 returndatasize swap1 dup3 + tag_5 + jump\t// in + tag_46: + /* \"C\":336:337 _ */ + tag_5 + jump\t// in + tag_45: + /* \"C\":336:337 _ */ returndatacopy returndatasize swap1 @@ -453,6 +530,10 @@ sub_0: assembly { swap2 sub slt + iszero + tag_48 + iszero + tag_47 tag_55 jumpi mload @@ -464,6 +545,20 @@ sub_0: assembly { 0x00 dup1 revert + tag_48: + pop + mload + swap2 + swap1 + pop + jump\t// out + tag_47: + pop + mload + swap2 + swap1 + pop + jump\t// out auxdata: } @@ -799,6 +894,19 @@ sub_0: assembly { address /* \"C\":403:411 this.f() */ extcodesize + tag_40 + jumpi + /* \"D\":91:166 contract D is C(3)... */ + dup2 + dup3 + revert + /* \"C\":403:411 this.f() */ + tag_40: + /* \"D\":91:166 contract D is C(3)... */ + /* \"C\":403:407 this */ + address + /* \"C\":403:411 this.f() */ + extcodesize iszero tag_43 jumpi @@ -826,6 +934,8 @@ sub_0: assembly { tag_45 jumpi dup1 + tag_41 + tag_40 swap3 tag_47 jumpi @@ -854,12 +964,22 @@ sub_0: assembly { swap1 jump\t// out /* \"C\":403:411 this.f() */ + tag_41: + tag_40: tag_47: /* \"D\":91:166 contract D is C(3)... */ swap1 swap2 pop /* \"C\":403:411 this.f() */ + dup2 + iszero + tag_42 + jumpi + dup2 + iszero + tag_41 + jumpi returndatasize /* \"D\":91:166 contract D is C(3)... */ 0x1f @@ -876,6 +996,10 @@ sub_0: assembly { dup4 lt or + iszero + tag_43 + iszero + tag_42 tag_51 jumpi pop @@ -889,26 +1013,56 @@ sub_0: assembly { /* \"C\":392:422 stateVar + this.f() + immutVar */ tag_50 /* \"D\":91:166 contract D is C(3)... */ + mstore + 0x24 + dup7 + revert + tag_43: + mstore + 0x24 + dup7 + revert + tag_42: swap5 0x40 mstore /* \"C\":403:411 this.f() */ + tag_44 + tag_43 returndatasize dup2 add swap1 tag_7 jump\t// in + tag_44: + swap1 + tag_43: + swap1 tag_53: swap2 dup2 swap4 pop + tag_42: + /* \"C\":392:411 stateVar + this.f() */ + tag_45 + tag_41: + /* \"C\":392:411 stateVar + this.f() */ + tag_44 jump(tag_48) /* \"D\":91:166 contract D is C(3)... */ tag_51: shl(0xe0, 0x4e487b71) dup2 + dup6 + tag_5 + jump\t// in + tag_45: + dup6 + tag_5 + jump\t// in + tag_44: mstore 0x41 /* \"C\":403:411 this.f() */ @@ -931,6 +1085,16 @@ sub_0: assembly { swap4 pop pop + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_46 + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ + /* \"C\":392:422 stateVar + this.f() + immutVar */ + tag_45 + /* \"C\":414:422 immutVar */ + immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") + /* \"C\":392:422 stateVar + this.f() + immutVar */ pop pop mload(0x40) @@ -938,6 +1102,14 @@ sub_0: assembly { returndatasize swap1 dup3 + tag_5 + jump\t// in + tag_46: + /* \"C\":336:337 _ */ + tag_5 + jump\t// in + tag_45: + /* \"C\":336:337 _ */ returndatacopy returndatasize swap1 @@ -963,6 +1135,10 @@ sub_0: assembly { swap2 sub slt + iszero + tag_48 + iszero + tag_47 tag_55 jumpi mload @@ -974,6 +1150,20 @@ sub_0: assembly { 0x00 dup1 revert + tag_48: + pop + mload + swap2 + swap1 + pop + jump\t// out + tag_47: + pop + mload + swap2 + swap1 + pop + jump\t// out auxdata: } diff --git a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json index 6a105aadde..2acd68ff75 100644 --- a/test/cmdlineTests/standard_debug_info_in_yul_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_yul_location/output.json @@ -526,7 +526,6 @@ object \"C_54\" { let expr_46_address := convert_t_contract$_C_$54_to_t_address(expr_45_address) let expr_46_functionSelector := 0x26121ff0 /// @src 0:410:418 \"this.f()\" - if iszero(extcodesize(expr_46_address)) { revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20() } // storage for arguments and returned data let _10 := allocate_unbounded() @@ -640,7 +639,7 @@ object \"C_54\" { case 0x26121ff0 { if callvalue() { revert(_1, _1) } abi_decode(calldatasize()) - let ret := /** @src 0:286:305 \"constVar + immutVar\" */ checked_add_int256_566(/** @src 0:297:305 \"immutVar\" */ loadimmutable(\"8\")) + let ret := /** @src 0:286:305 \"constVar + immutVar\" */ checked_add_int256_556(/** @src 0:297:305 \"immutVar\" */ loadimmutable(\"8\")) /// @src 0:79:435 \"contract C...\" let memPos := mload(64) return(memPos, sub(abi_encode_int256(memPos, ret), memPos)) @@ -664,7 +663,7 @@ object \"C_54\" { if callvalue() { revert(_1, _1) } abi_decode(calldatasize()) let memPos_3 := mload(64) - return(memPos_3, sub(abi_encode_int256_565(memPos_3), memPos_3)) + return(memPos_3, sub(abi_encode_int256_555(memPos_3), memPos_3)) } } revert(0, 0) @@ -673,7 +672,7 @@ object \"C_54\" { { if slt(add(dataEnd, not(3)), 0) { revert(0, 0) } } - function abi_encode_int256_565(headStart) -> tail + function abi_encode_int256_555(headStart) -> tail { tail := add(headStart, 32) mstore(headStart, /** @src 0:124:126 \"41\" */ 0x29) @@ -690,7 +689,7 @@ object \"C_54\" { mstore(4, 0x11) revert(0, 0x24) } - function checked_add_int256_566(y) -> sum + function checked_add_int256_556(y) -> sum { if and(1, sgt(y, sub(shl(255, 1), 42))) { panic_error_0x11() } sum := add(/** @src 0:124:126 \"41\" */ 0x29, /** @src 0:79:435 \"contract C...\" */ y) @@ -712,13 +711,6 @@ object \"C_54\" { let ret := add(_3, 1) sstore(_2, ret) /// @src 0:410:418 \"this.f()\" - if iszero(extcodesize(/** @src 0:410:414 \"this\" */ address())) - /// @src 0:410:418 \"this.f()\" - { - /// @src 0:79:435 \"contract C...\" - revert(_2, _2) - } - /// @src 0:410:418 \"this.f()\" let _4 := /** @src 0:79:435 \"contract C...\" */ mload(64) /// @src 0:410:418 \"this.f()\" mstore(_4, /** @src 0:79:435 \"contract C...\" */ shl(228, 0x026121ff)) @@ -1359,7 +1351,6 @@ object \"D_72\" { let expr_46_address := convert_t_contract$_C_$54_to_t_address(expr_45_address) let expr_46_functionSelector := 0x26121ff0 /// @src 0:410:418 \"this.f()\" - if iszero(extcodesize(expr_46_address)) { revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20() } // storage for arguments and returned data let _10 := allocate_unbounded() @@ -1481,7 +1472,7 @@ object \"D_72\" { case 0x26121ff0 { if callvalue() { revert(_1, _1) } abi_decode(calldatasize()) - let ret := /** @src 0:286:305 \"constVar + immutVar\" */ checked_add_int256_566(/** @src 0:297:305 \"immutVar\" */ loadimmutable(\"8\")) + let ret := /** @src 0:286:305 \"constVar + immutVar\" */ checked_add_int256_556(/** @src 0:297:305 \"immutVar\" */ loadimmutable(\"8\")) /// @src 1:91:166 \"contract D is C(3)...\" let memPos := mload(64) return(memPos, sub(abi_encode_int256(memPos, ret), memPos)) @@ -1505,7 +1496,7 @@ object \"D_72\" { if callvalue() { revert(_1, _1) } abi_decode(calldatasize()) let memPos_3 := mload(64) - return(memPos_3, sub(abi_encode_int256_565(memPos_3), memPos_3)) + return(memPos_3, sub(abi_encode_int256_555(memPos_3), memPos_3)) } } revert(0, 0) @@ -1514,7 +1505,7 @@ object \"D_72\" { { if slt(add(dataEnd, not(3)), 0) { revert(0, 0) } } - function abi_encode_int256_565(headStart) -> tail + function abi_encode_int256_555(headStart) -> tail { tail := add(headStart, 32) mstore(headStart, /** @src 0:124:126 \"41\" */ 0x29) @@ -1531,7 +1522,7 @@ object \"D_72\" { mstore(4, 0x11) revert(0, 0x24) } - function checked_add_int256_566(y) -> sum + function checked_add_int256_556(y) -> sum { if and(1, sgt(y, sub(shl(255, 1), 42))) { panic_error_0x11() } sum := add(/** @src 0:124:126 \"41\" */ 0x29, /** @src 1:91:166 \"contract D is C(3)...\" */ y) @@ -1553,13 +1544,6 @@ object \"D_72\" { let ret := add(_3, 1) sstore(_2, ret) /// @src 0:410:418 \"this.f()\" - if iszero(extcodesize(/** @src 0:410:414 \"this\" */ address())) - /// @src 0:410:418 \"this.f()\" - { - /// @src 1:91:166 \"contract D is C(3)...\" - revert(_2, _2) - } - /// @src 0:410:418 \"this.f()\" let _4 := /** @src 1:91:166 \"contract D is C(3)...\" */ mload(64) /// @src 0:410:418 \"this.f()\" mstore(_4, /** @src 1:91:166 \"contract D is C(3)...\" */ shl(228, 0x026121ff)) diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index ddd536a380..947f5cb234 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -61,9 +61,9 @@ contract C { // ---- // test_bytes() -> // gas irOptimized: 377545 -// gas legacy: 423563 +// gas legacy: 418955 // gas legacyOptimized: 331391 // test_uint256() -> // gas irOptimized: 528726 -// gas legacy: 591392 +// gas legacy: 586784 // gas legacyOptimized: 456137 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol index 8fe170e917..886d9dfd90 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -27,5 +27,5 @@ contract C { // library: L // f() -> 8, 7, 1, 2, 7, 12 // gas irOptimized: 167580 -// gas legacy: 169475 +// gas legacy: 169347 // gas legacyOptimized: 167397 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index 3a4a23fef7..f75eecfb59 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -62,9 +62,9 @@ contract C { // ---- // test_bytes() -> // gas irOptimized: 377545 -// gas legacy: 423563 +// gas legacy: 418955 // gas legacyOptimized: 331391 // test_uint256() -> // gas irOptimized: 528726 -// gas legacy: 591392 +// gas legacy: 586784 // gas legacyOptimized: 456137 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol index b730f3588d..49b93cbbcd 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol @@ -33,5 +33,5 @@ contract C is B { // ---- // test() -> 77 // gas irOptimized: 120044 -// gas legacy: 155221 +// gas legacy: 155093 // gas legacyOptimized: 111678 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol index 7832ef601e..28658089ad 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol @@ -41,4 +41,4 @@ contract C is B { // ---- // test() -> 5, 10 // gas irOptimized: 87578 -// gas legacy: 99137 +// gas legacy: 98881 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index bf42f87761..131430aa56 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -22,5 +22,5 @@ contract C { // f(uint256[][1]): 32, 32, 1, 42 -> true // f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true // gas irOptimized: 172204 -// gas legacy: 141900 +// gas legacy: 141644 // gas legacyOptimized: 121788 diff --git a/test/libsolidity/semanticTests/arithmetics/check_var_init.sol b/test/libsolidity/semanticTests/arithmetics/check_var_init.sol index f8e4ca2a4a..7e3edc127a 100644 --- a/test/libsolidity/semanticTests/arithmetics/check_var_init.sol +++ b/test/libsolidity/semanticTests/arithmetics/check_var_init.sol @@ -18,4 +18,4 @@ contract D { // ---- // f() -> FAILURE, hex"4e487b71", 0x11 // g(), 100 wei -> 1 -// gas legacy: 101918 +// gas legacy: 101790 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol index 5e30621af2..063e0bf9c0 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol @@ -22,5 +22,5 @@ contract B { // ---- // f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004 // gas irOptimized: 130328 -// gas legacy: 235199 +// gas legacy: 234943 // gas legacyOptimized: 133119 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index 95cb52f112..6edae71981 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -46,5 +46,5 @@ contract C { // ---- // test() -> 5, 6, 7 // gas irOptimized: 302321 -// gas legacy: 462080 +// gas legacy: 452172 // gas legacyOptimized: 294938 diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index 7d2b4d9957..a8a534b920 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -27,5 +27,5 @@ contract Main { // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 // gas irOptimized: 113776 -// gas legacy: 126852 +// gas legacy: 126596 // gas legacyOptimized: 114079 diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index 63c2acbb50..7016e6c6ec 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -27,5 +27,5 @@ contract Creator { // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 // gas irOptimized: 456873 -// gas legacy: 590939 +// gas legacy: 590683 // gas legacyOptimized: 448582 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index d4d41d80c2..1aba4c7c47 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -27,5 +27,5 @@ contract Creator { // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" // gas irOptimized: 308702 -// gas legacy: 429173 +// gas legacy: 428917 // gas legacyOptimized: 298384 diff --git a/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol b/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol index 78466f3f0b..f1043f559b 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_function_complex.sol @@ -19,4 +19,4 @@ contract C { // compileViaYul: also // ---- // f() -> 16 -// gas legacy: 103744 +// gas legacy: 103488 diff --git a/test/libsolidity/semanticTests/freeFunctions/new_operator.sol b/test/libsolidity/semanticTests/freeFunctions/new_operator.sol index 1694b64d5d..0e89c75604 100644 --- a/test/libsolidity/semanticTests/freeFunctions/new_operator.sol +++ b/test/libsolidity/semanticTests/freeFunctions/new_operator.sol @@ -15,4 +15,4 @@ contract D { // compileViaYul: also // ---- // f() -> 2 -// gas legacy: 101754 +// gas legacy: 101626 diff --git a/test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol b/test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol index 8546c775e8..0ab6fe0c3c 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol @@ -13,4 +13,4 @@ contract D { // compileViaYul: also // ---- // f() -> 2 -// gas legacy: 101727 +// gas legacy: 101599 diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index b50890f559..49c6a80a97 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -19,7 +19,7 @@ contract C { // ---- // constructor(), 20 wei // gas irOptimized: 220113 -// gas legacy: 288299 +// gas legacy: 294569 // gas legacyOptimized: 177933 // f(uint256): 20 -> 1370859564726510389319704988634906228201275401179 // x() -> 1 @@ -27,7 +27,7 @@ contract C { // x() -> 1 // stack(uint256): 1023 -> FAILURE // gas irOptimized: 345821 -// gas legacy: 535367 +// gas legacy: 483942 // gas legacyOptimized: 354656 // x() -> 1 // stack(uint256): 10 -> 693016686122178122849713379390321835634789309880 diff --git a/test/libsolidity/semanticTests/functionTypes/store_function.sol b/test/libsolidity/semanticTests/functionTypes/store_function.sol index c2678a91de..9200bd1205 100644 --- a/test/libsolidity/semanticTests/functionTypes/store_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/store_function.sol @@ -29,5 +29,5 @@ contract C { // ---- // t() -> 9 // gas irOptimized: 99186 -// gas legacy: 159083 +// gas legacy: 158955 // gas legacyOptimized: 108916 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index cd5992ce6e..d4300cfe13 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -30,7 +30,7 @@ contract C { // ---- // f() -> 3, 7, 5 // gas irOptimized: 127592 -// gas legacy: 151590 +// gas legacy: 151334 // gas legacyOptimized: 125422 // x() -> 7 // y() -> 5 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index 0dc9845f4d..8c9c6195c5 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -24,7 +24,7 @@ contract D { // ---- // f() -> 1 // gas irOptimized: 77164 -// gas legacy: 115012 +// gas legacy: 114884 // g() -> 5 // gas irOptimized: 77231 -// gas legacy: 115558 +// gas legacy: 115430 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol index e012accafe..7322e5f96b 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol @@ -26,4 +26,4 @@ contract B { // ---- // g() -> 42 // gas irOptimized: 80945 -// gas legacy: 125609 +// gas legacy: 125481 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol index 4105577f05..9b5f9778ca 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -26,5 +26,5 @@ contract B { // ---- // g() -> 42 // gas irOptimized: 111913 -// gas legacy: 185181 +// gas legacy: 185053 // gas legacyOptimized: 114726 diff --git a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol index 9a095cc21d..a400531ca8 100644 --- a/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol +++ b/test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol @@ -22,6 +22,6 @@ contract A { // compileViaYul: also // ---- // g(int256): -1 -> -1 -// gas legacy: 103622 +// gas legacy: 103494 // g(int256): 10 -> 10 -// gas legacy: 103250 +// gas legacy: 103122 diff --git a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol index 11cb938320..5dfeb9a69d 100644 --- a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol +++ b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol @@ -40,7 +40,7 @@ contract C { // gas irOptimized: 85640 // convertSubA() -> 1, 2 // gas irOptimized: 86395 -// gas legacy: 99303 +// gas legacy: 99047 // convertSubB() -> 1, 3 // gas irOptimized: 86338 -// gas legacy: 99237 +// gas legacy: 98981 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol index 17edaf3eb4..2d1070e2a8 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -23,5 +23,5 @@ contract A { // ---- // f(), 10 ether -> 3007, 3008, 3009 // gas irOptimized: 273275 -// gas legacy: 422885 +// gas legacy: 422501 // gas legacyOptimized: 287856 diff --git a/test/libsolidity/semanticTests/smoke/alignment.sol b/test/libsolidity/semanticTests/smoke/alignment.sol index 1434734615..80c69bb438 100644 --- a/test/libsolidity/semanticTests/smoke/alignment.sol +++ b/test/libsolidity/semanticTests/smoke/alignment.sol @@ -27,5 +27,5 @@ contract D { // stateDecimal() -> right(42) // stateBytes() -> left(0x4200ef) // internalStateDecimal() -> 0x20 -// gas legacy: 101807 +// gas legacy: 101679 // update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef) diff --git a/test/libsolidity/semanticTests/various/code_access_content.sol b/test/libsolidity/semanticTests/various/code_access_content.sol index 3f8d56587d..39ac71b540 100644 --- a/test/libsolidity/semanticTests/various/code_access_content.sol +++ b/test/libsolidity/semanticTests/various/code_access_content.sol @@ -42,4 +42,4 @@ contract C { // testRuntime() -> true // gas legacy: 101579 // testCreation() -> true -// gas legacy: 102137 +// gas legacy: 102009 diff --git a/test/libsolidity/semanticTests/various/code_access_create.sol b/test/libsolidity/semanticTests/various/code_access_create.sol index c32135fe5f..ce0d6305db 100644 --- a/test/libsolidity/semanticTests/various/code_access_create.sol +++ b/test/libsolidity/semanticTests/various/code_access_create.sol @@ -26,4 +26,4 @@ contract C { // compileViaYul: also // ---- // test() -> 7 -// gas legacy: 102392 +// gas legacy: 102264 diff --git a/test/libsolidity/semanticTests/various/external_types_in_calls.sol b/test/libsolidity/semanticTests/various/external_types_in_calls.sol index 229e93fc16..1b50465b4f 100644 --- a/test/libsolidity/semanticTests/various/external_types_in_calls.sol +++ b/test/libsolidity/semanticTests/various/external_types_in_calls.sol @@ -27,5 +27,5 @@ contract C { // compileViaYul: also // ---- // test() -> 9, 7 -// gas legacy: 130016 +// gas legacy: 129760 // t2() -> 9 diff --git a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol index 8ef472136a..25d7b3c78d 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -23,5 +23,5 @@ contract C { // ---- // g() -> 2, 6 // gas irOptimized: 178953 -// gas legacy: 180890 +// gas legacy: 180762 // gas legacyOptimized: 179609 diff --git a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol index ab6d6e59a0..cc910826bd 100644 --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol @@ -36,12 +36,12 @@ contract D { // compileViaYul: also // ---- // f() -> 0x1 # This should work, next should throw # -// gas legacy: 103844 +// gas legacy: 103716 // fview() -> FAILURE // gas irOptimized: 98438627 -// gas legacy: 98438803 +// gas legacy: 98438801 // gas legacyOptimized: 98438596 // fpure() -> FAILURE // gas irOptimized: 98438627 -// gas legacy: 98438803 +// gas legacy: 98438801 // gas legacyOptimized: 98438597 From 31c504c5baa24898f71790e42f4a626c15dca3a1 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 28 Oct 2021 12:35:06 +0200 Subject: [PATCH 0092/1748] Add test for extcodesize check. --- .../external_call_at_construction_time.sol | 28 +++++++++++++ .../external_call_to_nonexisting.sol | 36 +++++++++++++++++ ...ernal_call_to_nonexisting_debugstrings.sol | 39 +++++++++++++++++++ .../precompile_extcodesize_check.sol | 11 +++++- 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol create mode 100644 test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol create mode 100644 test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol diff --git a/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol new file mode 100644 index 0000000000..d5b0d09740 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol @@ -0,0 +1,28 @@ +pragma solidity >= 0.6.0; + +// This tests skipping the extcodesize check. + +contract T { + constructor() { this.f(); } + function f() external {} +} +contract U { + constructor() { this.f(); } + function f() external returns (uint) {} +} + +contract C { + function f(uint c) external returns (uint) { + if (c == 0) new T(); + else if (c == 1) new U(); + return 1 + c; + } +} + +// ==== +// EVMVersion: >=byzantium +// compileViaYul: also +// ---- +// f(uint256): 0 -> FAILURE +// f(uint256): 1 -> FAILURE +// f(uint256): 2 -> 3 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol new file mode 100644 index 0000000000..9546f10986 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol @@ -0,0 +1,36 @@ +// This tests skipping the extcodesize check. + +interface I { + function a() external pure; + function b() external; + function c() external payable; + function x() external returns (uint); + function y() external returns (string memory); +} +contract C { + I i = I(address(0xcafecafe)); + constructor() payable {} + function f(uint c) external returns (uint) { + if (c == 0) i.a(); + else if (c == 1) i.b(); + else if (c == 2) i.c(); + else if (c == 3) i.c{value: 1}(); + else if (c == 4) i.x(); + else if (c == 5) i.y(); + return 1 + c; + } +} + +// ==== +// compileViaYul: also +// ---- +// constructor(), 1 ether -> +// gas legacy: 465314 +// gas legacyOptimized: 510004 +// f(uint256): 0 -> FAILURE +// f(uint256): 1 -> FAILURE +// f(uint256): 2 -> FAILURE +// f(uint256): 3 -> FAILURE +// f(uint256): 4 -> FAILURE +// f(uint256): 5 -> FAILURE +// f(uint256): 6 -> 7 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol new file mode 100644 index 0000000000..ca635d3108 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -0,0 +1,39 @@ +pragma solidity >= 0.6.0; + +// This tests skipping the extcodesize check. + +interface I { + function a() external pure; + function b() external; + function c() external payable; + function x() external returns (uint); + function y() external returns (string memory); +} +contract C { + I i = I(address(0xcafecafe)); + constructor() payable {} + function f(uint c) external returns (uint) { + if (c == 0) i.a(); + else if (c == 1) i.b(); + else if (c == 2) i.c(); + else if (c == 3) i.c{value: 1}(); + else if (c == 4) i.x(); + else if (c == 5) i.y(); + return 1 + c; + } +} + +// ==== +// EVMVersion: >=byzantium +// compileViaYul: also +// revertStrings: debug +// ---- +// constructor(), 1 ether -> +// gas legacyOptimized: 510004 +// f(uint256): 0 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 1 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 2 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 3 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 4 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 5 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 6 -> 7 diff --git a/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol index 7a9025e26c..c07adb9094 100644 --- a/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol +++ b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol @@ -1,13 +1,21 @@ interface Identity { function selectorAndAppendValue(uint value) external pure returns (uint); } +interface ReturnMoreData { + function f(uint value) external pure returns (uint, uint, uint); +} contract C { Identity constant i = Identity(address(0x0004)); function testHighLevel() external pure returns (bool) { - // Should fail because `extcodesize(4) = 0` + // Works because the extcodesize check is skipped + // and the precompiled contract returns actual data. i.selectorAndAppendValue(5); return true; } + function testHighLevel2() external pure returns (uint, uint, uint) { + // Fails because the identity contract does not return enough data. + return ReturnMoreData(address(4)).f(2); + } function testLowLevel() external view returns (uint value) { (bool success, bytes memory ret) = address(4).staticcall( @@ -23,3 +31,4 @@ contract C { // ---- // testHighLevel() -> FAILURE // testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000 +// testHighLevel2() -> FAILURE From f320a95dd9be698df9fa7a3c12a7efc1a22a1521 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 2 Nov 2021 12:04:31 +0100 Subject: [PATCH 0093/1748] Update documentation. --- docs/control-structures.rst | 11 ++++++++++- docs/introduction-to-smart-contracts.rst | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 49e66537d3..84b65918d3 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -114,10 +114,19 @@ otherwise, the ``value`` option would not be available. Due to the fact that the EVM considers a call to a non-existing contract to always succeed, Solidity uses the ``extcodesize`` opcode to check that the contract that is about to be called actually exists (it contains code) -and causes an exception if it does not. +and causes an exception if it does not. This check is skipped if the return +data will be decoded after the call and thus the ABI decoder will catch the +case of a non-existing contract. + Note that this check is not performed in case of :ref:`low-level calls ` which operate on addresses rather than contract instances. +.. note:: + Be careful when using high-level calls to + :ref:`precompiled contracts `, + since the compiler considers them non-existing according to the + above logic even though they execute code and can return data. + Function calls also cause exceptions if the called contract itself throws an exception or goes out of gas. diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index c22d4e6fa9..d19a0decf8 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -565,3 +565,24 @@ contracts, the Ether is forever lost. If you want to deactivate your contracts, you should instead **disable** them by changing some internal state which causes all functions to revert. This makes it impossible to use the contract, as it returns Ether immediately. + + +.. index:: ! precompiled contracts, ! precompiles, ! contract;precompiled + +.. _precompiledContracts: + +Precompiled Contracts +===================== + +There is a small set of contract addresses that are special: +The address range between ``1`` and (including) ``8`` contains +"precompiled contracts" that can be called as any other contract +but their behaviour (and their gas consumption) is not defined +by EVM code stored at that address (they do not contain code) +but instead is implemented in the EVM execution environment itself. + +Different EVM-compatible chains might use a different set of +precompiled contracts. It might also be possible that new +precompiled contracts are added to the Ethereum main chain in the future, +but you can reasonabyly expect them to always be in the range between +``1`` and ``0xffff`` (inclusive). \ No newline at end of file From 080c7245aebdb4e7ab1d2b2f3a6194244eda976f Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 4 Nov 2021 18:20:10 +0100 Subject: [PATCH 0094/1748] Update tests. --- .../output.json | 312 +++--------------- .../abi_encode_calldata_slice.sol | 8 +- .../struct/struct_storage_ptr.sol | 4 +- .../abi_encode_calldata_slice.sol | 8 +- ...2_in_function_inherited_in_v1_contract.sol | 4 +- ...ode_v2_in_modifier_used_in_v1_contract.sol | 2 +- .../abiEncoderV2/calldata_array.sol | 4 +- .../array/fixed_arrays_as_return_type.sol | 4 +- .../array/function_array_cross_calls.sol | 4 +- .../semanticTests/array/reusing_memory.sol | 4 +- .../constructor/arrays_in_constructors.sol | 4 +- .../bytes_in_constructors_packer.sol | 4 +- .../external_call_at_construction_time.sol | 2 - ...ernal_call_to_nonexisting_debugstrings.sol | 2 - .../functionCall/failed_create.sol | 8 +- .../precompile_extcodesize_check.sol | 4 +- .../functionTypes/store_function.sol | 4 +- .../immutable/multi_creation.sol | 4 +- .../address_overload_resolution.sol | 4 +- ...d_function_calldata_calldata_interface.sol | 2 +- ...ted_function_calldata_memory_interface.sol | 4 +- .../interface_inheritance_conversions.sol | 6 +- .../salted_create_with_value.sol | 4 +- .../skip_dynamic_types_for_structs.sol | 4 +- .../various/staticcall_for_view_and_pure.sol | 8 +- 25 files changed, 95 insertions(+), 323 deletions(-) diff --git a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json index 773637b321..1c3999afcf 100644 --- a/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json +++ b/test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json @@ -285,40 +285,18 @@ sub_0: assembly { dup2 dup2 sstore - /* \"C\":403:407 this */ - address - /* \"C\":403:411 this.f() */ - extcodesize - tag_40 - jumpi - /* \"C\":79:428 contract C... */ - dup2 - dup3 - revert - /* \"C\":403:411 this.f() */ - tag_40: - /* \"C\":79:428 contract C... */ - /* \"C\":403:407 this */ - address - /* \"C\":403:411 this.f() */ - extcodesize - iszero - tag_43 - jumpi - /* \"C\":79:428 contract C... */ mload(0x40) shl(0xe4, 0x026121ff) /* \"C\":403:411 this.f() */ dup2 mstore 0x20 - /* \"C\":79:428 contract C... */ + /* \"C\":403:407 this */ dup2 /* \"C\":403:411 this.f() */ 0x04 - /* \"C\":79:428 contract C... */ - dup2 /* \"C\":403:407 this */ + dup2 address /* \"C\":403:411 this.f() */ gas @@ -326,55 +304,43 @@ sub_0: assembly { swap2 dup3 iszero - tag_45 + tag_43 jumpi dup1 - tag_41 - tag_40 swap3 - tag_47 + tag_45 jumpi /* \"C\":304:341 modifier m()... */ - tag_48: + tag_46: /* \"C\":392:411 stateVar + this.f() */ pop pop - tag_49 + tag_47 swap1 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_50 + tag_48 /* \"C\":392:411 stateVar + this.f() */ swap3 tag_5 jump\t// in - tag_49: + tag_47: /* \"C\":414:422 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":392:422 stateVar + this.f() + immutVar */ swap1 tag_5 jump\t// in - tag_50: + tag_48: /* \"C\":304:341 modifier m()... */ swap1 jump\t// out /* \"C\":403:411 this.f() */ - tag_41: - tag_40: - tag_47: + tag_45: /* \"C\":79:428 contract C... */ swap1 swap2 pop /* \"C\":403:411 this.f() */ - dup2 - iszero - tag_42 - jumpi - dup2 - iszero - tag_41 - jumpi returndatasize /* \"C\":79:428 contract C... */ 0x1f @@ -391,73 +357,39 @@ sub_0: assembly { dup4 lt or - iszero - tag_43 - iszero - tag_42 - tag_51 + tag_49 jumpi pop swap2 /* \"C\":403:411 this.f() */ - tag_53 + tag_51 /* \"C\":392:411 stateVar + this.f() */ - tag_49 + tag_47 /* \"C\":79:428 contract C... */ swap3 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_50 + tag_48 /* \"C\":79:428 contract C... */ - mstore - 0x24 - dup7 - revert - tag_43: - mstore - 0x24 - dup7 - revert - tag_42: swap5 0x40 mstore /* \"C\":403:411 this.f() */ - tag_44 - tag_43 returndatasize dup2 add swap1 tag_7 jump\t// in - tag_44: - swap1 - tag_43: - swap1 - tag_53: + tag_51: swap2 dup2 swap4 pop - tag_42: - /* \"C\":392:411 stateVar + this.f() */ - tag_45 - tag_41: - /* \"C\":392:411 stateVar + this.f() */ - tag_44 - jump(tag_48) + jump(tag_46) /* \"C\":79:428 contract C... */ - tag_51: + tag_49: shl(0xe0, 0x4e487b71) dup2 - dup6 - tag_5 - jump\t// in - tag_45: - dup6 - tag_5 - jump\t// in - tag_44: mstore 0x41 /* \"C\":403:411 this.f() */ @@ -475,53 +407,27 @@ sub_0: assembly { /* \"C\":79:428 contract C... */ revert /* \"C\":403:411 this.f() */ - tag_45: + tag_43: /* \"C\":79:428 contract C... */ swap4 pop pop pop - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_46 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_45 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ pop mload(0x40) swap1 returndatasize swap1 dup3 - tag_5 - jump\t// in - tag_46: - /* \"C\":336:337 _ */ - tag_5 - jump\t// in - tag_45: - /* \"C\":336:337 _ */ returndatacopy returndatasize swap1 - revert - /* \"C\":403:411 this.f() */ - tag_43: - /* \"C\":79:428 contract C... */ - swap2 - pop - pop - dup1 revert tag_41: - tag_54 + tag_52 tag_3 jump\t// in - tag_54: + tag_52: jump(tag_42) tag_7: swap1 @@ -530,35 +436,17 @@ sub_0: assembly { swap2 sub slt - iszero - tag_48 - iszero - tag_47 - tag_55 + tag_53 jumpi mload swap1 jump\t// out - tag_55: + tag_53: pop pop 0x00 dup1 revert - tag_48: - pop - mload - swap2 - swap1 - pop - jump\t// out - tag_47: - pop - mload - swap2 - swap1 - pop - jump\t// out auxdata: } @@ -890,40 +778,18 @@ sub_0: assembly { dup2 dup2 sstore - /* \"C\":403:407 this */ - address - /* \"C\":403:411 this.f() */ - extcodesize - tag_40 - jumpi - /* \"D\":91:166 contract D is C(3)... */ - dup2 - dup3 - revert - /* \"C\":403:411 this.f() */ - tag_40: - /* \"D\":91:166 contract D is C(3)... */ - /* \"C\":403:407 this */ - address - /* \"C\":403:411 this.f() */ - extcodesize - iszero - tag_43 - jumpi - /* \"D\":91:166 contract D is C(3)... */ mload(0x40) shl(0xe4, 0x026121ff) /* \"C\":403:411 this.f() */ dup2 mstore 0x20 - /* \"D\":91:166 contract D is C(3)... */ + /* \"C\":403:407 this */ dup2 /* \"C\":403:411 this.f() */ 0x04 - /* \"D\":91:166 contract D is C(3)... */ - dup2 /* \"C\":403:407 this */ + dup2 address /* \"C\":403:411 this.f() */ gas @@ -931,55 +797,43 @@ sub_0: assembly { swap2 dup3 iszero - tag_45 + tag_43 jumpi dup1 - tag_41 - tag_40 swap3 - tag_47 + tag_45 jumpi /* \"C\":304:341 modifier m()... */ - tag_48: + tag_46: /* \"C\":392:411 stateVar + this.f() */ pop pop - tag_49 + tag_47 swap1 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_50 + tag_48 /* \"C\":392:411 stateVar + this.f() */ swap3 tag_5 jump\t// in - tag_49: + tag_47: /* \"C\":414:422 immutVar */ immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") /* \"C\":392:422 stateVar + this.f() + immutVar */ swap1 tag_5 jump\t// in - tag_50: + tag_48: /* \"C\":304:341 modifier m()... */ swap1 jump\t// out /* \"C\":403:411 this.f() */ - tag_41: - tag_40: - tag_47: + tag_45: /* \"D\":91:166 contract D is C(3)... */ swap1 swap2 pop /* \"C\":403:411 this.f() */ - dup2 - iszero - tag_42 - jumpi - dup2 - iszero - tag_41 - jumpi returndatasize /* \"D\":91:166 contract D is C(3)... */ 0x1f @@ -996,73 +850,39 @@ sub_0: assembly { dup4 lt or - iszero - tag_43 - iszero - tag_42 - tag_51 + tag_49 jumpi pop swap2 /* \"C\":403:411 this.f() */ - tag_53 + tag_51 /* \"C\":392:411 stateVar + this.f() */ - tag_49 + tag_47 /* \"D\":91:166 contract D is C(3)... */ swap3 /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_50 + tag_48 /* \"D\":91:166 contract D is C(3)... */ - mstore - 0x24 - dup7 - revert - tag_43: - mstore - 0x24 - dup7 - revert - tag_42: swap5 0x40 mstore /* \"C\":403:411 this.f() */ - tag_44 - tag_43 returndatasize dup2 add swap1 tag_7 jump\t// in - tag_44: - swap1 - tag_43: - swap1 - tag_53: + tag_51: swap2 dup2 swap4 pop - tag_42: - /* \"C\":392:411 stateVar + this.f() */ - tag_45 - tag_41: - /* \"C\":392:411 stateVar + this.f() */ - tag_44 - jump(tag_48) + jump(tag_46) /* \"D\":91:166 contract D is C(3)... */ - tag_51: + tag_49: shl(0xe0, 0x4e487b71) dup2 - dup6 - tag_5 - jump\t// in - tag_45: - dup6 - tag_5 - jump\t// in - tag_44: mstore 0x41 /* \"C\":403:411 this.f() */ @@ -1080,21 +900,11 @@ sub_0: assembly { /* \"D\":91:166 contract D is C(3)... */ revert /* \"C\":403:411 this.f() */ - tag_45: + tag_43: /* \"D\":91:166 contract D is C(3)... */ swap4 pop pop - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_46 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ - /* \"C\":392:422 stateVar + this.f() + immutVar */ - tag_45 - /* \"C\":414:422 immutVar */ - immutable(\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\") - /* \"C\":392:422 stateVar + this.f() + immutVar */ pop pop mload(0x40) @@ -1102,31 +912,15 @@ sub_0: assembly { returndatasize swap1 dup3 - tag_5 - jump\t// in - tag_46: - /* \"C\":336:337 _ */ - tag_5 - jump\t// in - tag_45: - /* \"C\":336:337 _ */ returndatacopy returndatasize swap1 - revert - /* \"C\":403:411 this.f() */ - tag_43: - /* \"D\":91:166 contract D is C(3)... */ - swap2 - pop - pop - dup1 revert tag_41: - tag_54 + tag_52 tag_3 jump\t// in - tag_54: + tag_52: jump(tag_42) tag_7: swap1 @@ -1135,35 +929,17 @@ sub_0: assembly { swap2 sub slt - iszero - tag_48 - iszero - tag_47 - tag_55 + tag_53 jumpi mload swap1 jump\t// out - tag_55: + tag_53: pop pop 0x00 dup1 revert - tag_48: - pop - mload - swap2 - swap1 - pop - jump\t// out - tag_47: - pop - mload - swap2 - swap1 - pop - jump\t// out auxdata: } diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index 947f5cb234..e54c39d322 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -60,10 +60,10 @@ contract C { // compileViaYul: also // ---- // test_bytes() -> -// gas irOptimized: 377545 +// gas irOptimized: 373483 // gas legacy: 418955 -// gas legacyOptimized: 331391 +// gas legacyOptimized: 326783 // test_uint256() -> -// gas irOptimized: 528726 +// gas irOptimized: 524664 // gas legacy: 586784 -// gas legacyOptimized: 456137 +// gas legacyOptimized: 451529 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol index 886d9dfd90..19d9b1b9a4 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -26,6 +26,6 @@ contract C { // ---- // library: L // f() -> 8, 7, 1, 2, 7, 12 -// gas irOptimized: 167580 +// gas irOptimized: 167446 // gas legacy: 169347 -// gas legacyOptimized: 167397 +// gas legacyOptimized: 167269 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index f75eecfb59..53aeb89499 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -61,10 +61,10 @@ contract C { // compileViaYul: also // ---- // test_bytes() -> -// gas irOptimized: 377545 +// gas irOptimized: 373483 // gas legacy: 418955 -// gas legacyOptimized: 331391 +// gas legacyOptimized: 326783 // test_uint256() -> -// gas irOptimized: 528726 +// gas irOptimized: 524664 // gas legacy: 586784 -// gas legacyOptimized: 456137 +// gas legacyOptimized: 451529 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol index 49b93cbbcd..953fa79455 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol @@ -32,6 +32,6 @@ contract C is B { // compileViaYul: also // ---- // test() -> 77 -// gas irOptimized: 120044 +// gas irOptimized: 119931 // gas legacy: 155093 -// gas legacyOptimized: 111678 +// gas legacyOptimized: 111550 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol index 28658089ad..1531183555 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol @@ -40,5 +40,5 @@ contract C is B { // compileViaYul: also // ---- // test() -> 5, 10 -// gas irOptimized: 87578 +// gas irOptimized: 87337 // gas legacy: 98881 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index 131430aa56..11fccbb610 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -21,6 +21,6 @@ contract C { // f(uint256[][1]): 32, 32, 0 -> true // f(uint256[][1]): 32, 32, 1, 42 -> true // f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true -// gas irOptimized: 172204 +// gas irOptimized: 171964 // gas legacy: 141644 -// gas legacyOptimized: 121788 +// gas legacyOptimized: 121532 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol index 063e0bf9c0..3b0a73d006 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol @@ -21,6 +21,6 @@ contract B { // compileViaYul: also // ---- // f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004 -// gas irOptimized: 130328 +// gas irOptimized: 130097 // gas legacy: 234943 -// gas legacyOptimized: 133119 +// gas legacyOptimized: 132863 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index 6edae71981..9c78c12070 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -45,6 +45,6 @@ contract C { // compileViaYul: also // ---- // test() -> 5, 6, 7 -// gas irOptimized: 302321 +// gas irOptimized: 290947 // gas legacy: 452172 -// gas legacyOptimized: 294938 +// gas legacyOptimized: 285017 diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index a8a534b920..ee1a57b1ee 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -26,6 +26,6 @@ contract Main { // compileViaYul: also // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 -// gas irOptimized: 113776 +// gas irOptimized: 113581 // gas legacy: 126596 -// gas legacyOptimized: 114079 +// gas legacyOptimized: 113823 diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index 7016e6c6ec..7885b24a34 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -26,6 +26,6 @@ contract Creator { // compileViaYul: also // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 -// gas irOptimized: 456873 +// gas irOptimized: 456668 // gas legacy: 590683 -// gas legacyOptimized: 448582 +// gas legacyOptimized: 448326 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index 1aba4c7c47..434b926fc6 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -26,6 +26,6 @@ contract Creator { // compileViaYul: also // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" -// gas irOptimized: 308702 +// gas irOptimized: 308497 // gas legacy: 428917 -// gas legacyOptimized: 298384 +// gas legacyOptimized: 298128 diff --git a/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol index d5b0d09740..2fb2f266d7 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol @@ -1,5 +1,3 @@ -pragma solidity >= 0.6.0; - // This tests skipping the extcodesize check. contract T { diff --git a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol index ca635d3108..f426e628eb 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -1,5 +1,3 @@ -pragma solidity >= 0.6.0; - // This tests skipping the extcodesize check. interface I { diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index 49c6a80a97..54cd9f06a5 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -18,17 +18,17 @@ contract C { // compileViaYul: also // ---- // constructor(), 20 wei -// gas irOptimized: 220113 +// gas irOptimized: 218775 // gas legacy: 294569 -// gas legacyOptimized: 177933 +// gas legacyOptimized: 174699 // f(uint256): 20 -> 1370859564726510389319704988634906228201275401179 // x() -> 1 // f(uint256): 20 -> FAILURE // x() -> 1 // stack(uint256): 1023 -> FAILURE -// gas irOptimized: 345821 +// gas irOptimized: 296769 // gas legacy: 483942 -// gas legacyOptimized: 354656 +// gas legacyOptimized: 298807 // x() -> 1 // stack(uint256): 10 -> 693016686122178122849713379390321835634789309880 // x() -> 2 diff --git a/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol index c07adb9094..b82c5f9b7d 100644 --- a/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol +++ b/test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol @@ -26,9 +26,9 @@ contract C { } // ==== -// compileViaYul: also // EVMVersion: >=constantinople +// compileViaYul: also // ---- -// testHighLevel() -> FAILURE +// testHighLevel() -> true // testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000 // testHighLevel2() -> FAILURE diff --git a/test/libsolidity/semanticTests/functionTypes/store_function.sol b/test/libsolidity/semanticTests/functionTypes/store_function.sol index 9200bd1205..dab82918a5 100644 --- a/test/libsolidity/semanticTests/functionTypes/store_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/store_function.sol @@ -28,6 +28,6 @@ contract C { // compileViaYul: also // ---- // t() -> 9 -// gas irOptimized: 99186 +// gas irOptimized: 99064 // gas legacy: 158955 -// gas legacyOptimized: 108916 +// gas legacyOptimized: 108788 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index d4300cfe13..2f74c17f55 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -29,8 +29,8 @@ contract C { // compileViaYul: also // ---- // f() -> 3, 7, 5 -// gas irOptimized: 127592 +// gas irOptimized: 127387 // gas legacy: 151334 -// gas legacyOptimized: 125422 +// gas legacyOptimized: 125166 // x() -> 7 // y() -> 5 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index 8c9c6195c5..6a9ff7c31a 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -23,8 +23,8 @@ contract D { // compileViaYul: also // ---- // f() -> 1 -// gas irOptimized: 77164 +// gas irOptimized: 77051 // gas legacy: 114884 // g() -> 5 -// gas irOptimized: 77231 +// gas irOptimized: 77106 // gas legacy: 115430 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol index 7322e5f96b..ed28477b2a 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol @@ -25,5 +25,5 @@ contract B { // compileViaYul: also // ---- // g() -> 42 -// gas irOptimized: 80945 +// gas irOptimized: 80813 // gas legacy: 125481 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol index 9b5f9778ca..46992694e3 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -25,6 +25,6 @@ contract B { // compileViaYul: also // ---- // g() -> 42 -// gas irOptimized: 111913 +// gas irOptimized: 111781 // gas legacy: 185053 -// gas legacyOptimized: 114726 +// gas legacyOptimized: 114598 diff --git a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol index 5dfeb9a69d..95f831e243 100644 --- a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol +++ b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol @@ -37,10 +37,10 @@ contract C { // compileViaYul: also // ---- // convertParent() -> 1 -// gas irOptimized: 85640 +// gas irOptimized: 85524 // convertSubA() -> 1, 2 -// gas irOptimized: 86395 +// gas irOptimized: 86155 // gas legacy: 99047 // convertSubB() -> 1, 3 -// gas irOptimized: 86338 +// gas irOptimized: 86098 // gas legacy: 98981 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol index 2d1070e2a8..e8fe016874 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -22,6 +22,6 @@ contract A { // compileViaYul: also // ---- // f(), 10 ether -> 3007, 3008, 3009 -// gas irOptimized: 273275 +// gas irOptimized: 272947 // gas legacy: 422501 -// gas legacyOptimized: 287856 +// gas legacyOptimized: 287472 diff --git a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol index 25d7b3c78d..cad181c8f4 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -22,6 +22,6 @@ contract C { // compileViaYul: also // ---- // g() -> 2, 6 -// gas irOptimized: 178953 +// gas irOptimized: 178835 // gas legacy: 180762 -// gas legacyOptimized: 179609 +// gas legacyOptimized: 179481 diff --git a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol index cc910826bd..1950f7a4d7 100644 --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol @@ -38,10 +38,10 @@ contract D { // f() -> 0x1 # This should work, next should throw # // gas legacy: 103716 // fview() -> FAILURE -// gas irOptimized: 98438627 +// gas irOptimized: 98438625 // gas legacy: 98438801 -// gas legacyOptimized: 98438596 +// gas legacyOptimized: 98438594 // fpure() -> FAILURE -// gas irOptimized: 98438627 +// gas irOptimized: 98438626 // gas legacy: 98438801 -// gas legacyOptimized: 98438597 +// gas legacyOptimized: 98438595 From ed907561ebe51be903d8e76742b7b7b93901b489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 25 Oct 2021 14:30:15 +0200 Subject: [PATCH 0095/1748] externalTests: Enable `set -e` in external tests --- test/externalTests/colony.sh | 3 +++ test/externalTests/ens.sh | 3 +++ test/externalTests/gnosis-v2.sh | 3 +++ test/externalTests/gnosis.sh | 3 +++ test/externalTests/solc-js/solc-js.sh | 3 +++ test/externalTests/zeppelin.sh | 3 +++ 6 files changed, 18 insertions(+) diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index c807f9022b..ef06f1d7b0 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -18,6 +18,9 @@ # # (c) 2019 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index 90c96d5a50..e3bdb229a5 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -18,6 +18,9 @@ # # (c) 2019 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 19ff3edcb8..338b2418f6 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -18,6 +18,9 @@ # # (c) 2020 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index f8ca999d62..a8a50782d5 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -18,6 +18,9 @@ # # (c) 2019 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh diff --git a/test/externalTests/solc-js/solc-js.sh b/test/externalTests/solc-js/solc-js.sh index 3762ba7a2f..fa0d7ccee3 100755 --- a/test/externalTests/solc-js/solc-js.sh +++ b/test/externalTests/solc-js/solc-js.sh @@ -18,6 +18,9 @@ # # (c) 2019 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 97da3d47bf..ca90d46f44 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -18,6 +18,9 @@ # # (c) 2019 solidity contributors. #------------------------------------------------------------------------------ + +set -e + source scripts/common.sh source test/externalTests/common.sh From bc2402e76f94cf4ec343d4873adc1485b9ccd720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Oct 2021 12:50:30 +0200 Subject: [PATCH 0096/1748] externalTests: Use named tmp dirs --- test/externalTests/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index bc24cd1d1e..f015b5fd76 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -251,7 +251,7 @@ function external_test printTask "Testing $name..." echo "===========================" - DIR=$(mktemp -d) + DIR=$(mktemp -d -t "ext-test-${name}-XXXXXX") ( if [ -z "$main_fn" ]; then printError "Test main function not defined." From fc224f74c7fbff547714a59470fab0d2b1410168 Mon Sep 17 00:00:00 2001 From: Marenz Date: Thu, 28 Oct 2021 15:30:31 +0200 Subject: [PATCH 0097/1748] Evaluate absolute paths for imports in 'parsing' stage --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 26 ++++--- libsolidity/interface/CompilerStack.h | 4 +- .../args | 1 + .../input.json | 12 ++++ .../output.json | 67 +++++++++++++++++++ .../not_existing_import_parseOnly.json | 1 + 7 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 test/cmdlineTests/standard_parsing_import_absolute_paths/args create mode 100644 test/cmdlineTests/standard_parsing_import_absolute_paths/input.json create mode 100644 test/cmdlineTests/standard_parsing_import_absolute_paths/output.json diff --git a/Changelog.md b/Changelog.md index ff183e22b2..aad7b2a53a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``. * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. * Commandline Interface: Use different colors when printing errors, warnings and infos. + * JSON AST: Set absolute paths of imports earlier, in the ``parsing`` stage. * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. * SMTChecker: Report contract invariants and reentrancy properties. This can be enabled via the CLI option ``--model-checker-invariants`` or the Standard JSON option ``settings.modelChecker.invariants``. * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9fa3cb1645..27e0f9d3ae 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -350,8 +350,22 @@ bool CompilerStack::parse() else { source.ast->annotation().path = path; + + for (auto const& import: ASTNode::filteredNodes(source.ast->nodes())) + { + solAssert(!import->path().empty(), "Import path cannot be empty."); + + // The current value of `path` is the absolute path as seen from this source file. + // We first have to apply remappings before we can store the actual absolute path + // as seen globally. + import->annotation().absolutePath = applyRemapping(util::absolutePath( + import->path(), + path + ), path); + } + if (m_stopAfter >= ParsedAndImported) - for (auto const& newSource: loadMissingSources(*source.ast, path)) + for (auto const& newSource: loadMissingSources(*source.ast)) { string const& newPath = newSource.first; string const& newContents = newSource.second; @@ -1091,7 +1105,7 @@ string const& CompilerStack::Source::ipfsUrl() const return ipfsUrlCached; } -StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string const& _sourcePath) +StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast) { solAssert(m_stackState < ParsedAndImported, ""); StringMap newSources; @@ -1100,14 +1114,8 @@ StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string for (auto const& node: _ast.nodes()) if (ImportDirective const* import = dynamic_cast(node.get())) { - solAssert(!import->path().empty(), "Import path cannot be empty."); + string const& importPath = *import->annotation().absolutePath; - string importPath = util::absolutePath(import->path(), _sourcePath); - // The current value of `path` is the absolute path as seen from this source file. - // We first have to apply remappings before we can store the actual absolute path - // as seen globally. - importPath = applyRemapping(importPath, _sourcePath); - import->annotation().absolutePath = importPath; if (m_sources.count(importPath) || newSources.count(importPath)) continue; diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index c97581a651..3609662e02 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -392,9 +392,9 @@ class CompilerStack: public langutil::CharStreamProvider void findAndReportCyclicContractDependencies(); /// Loads the missing sources from @a _ast (named @a _path) using the callback - /// @a m_readFile and stores the absolute paths of all imports in the AST annotations. + /// @a m_readFile /// @returns the newly loaded sources. - StringMap loadMissingSources(SourceUnit const& _ast, std::string const& _path); + StringMap loadMissingSources(SourceUnit const& _ast); std::string applyRemapping(std::string const& _path, std::string const& _context); void resolveImports(); diff --git a/test/cmdlineTests/standard_parsing_import_absolute_paths/args b/test/cmdlineTests/standard_parsing_import_absolute_paths/args new file mode 100644 index 0000000000..a905f1fe6a --- /dev/null +++ b/test/cmdlineTests/standard_parsing_import_absolute_paths/args @@ -0,0 +1 @@ +--pretty-json --json-indent 4 diff --git a/test/cmdlineTests/standard_parsing_import_absolute_paths/input.json b/test/cmdlineTests/standard_parsing_import_absolute_paths/input.json new file mode 100644 index 0000000000..9ec5150b45 --- /dev/null +++ b/test/cmdlineTests/standard_parsing_import_absolute_paths/input.json @@ -0,0 +1,12 @@ +{ + "language": "Solidity", + "sources": { + "/project/../C.sol": {"content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\nimport \"../L.sol\";"}, + "/lib/L.sol": {"content": "//SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n"} + }, + "settings": { + "stopAfter": "parsing", + "remappings": [":/project/=/lib/"], + "outputSelection": {"*": {"": ["ast"]}} + } +} diff --git a/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json b/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json new file mode 100644 index 0000000000..1982561ef2 --- /dev/null +++ b/test/cmdlineTests/standard_parsing_import_absolute_paths/output.json @@ -0,0 +1,67 @@ +{ + "sources": + { + "/lib/L.sol": + { + "ast": + { + "absolutePath": "/lib/L.sol", + "id": 2, + "license": "GPL-2.0", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1, + "literals": + [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "35:22:0" + } + ], + "src": "35:23:0" + }, + "id": 0 + }, + "/project/../C.sol": + { + "ast": + { + "absolutePath": "/project/../C.sol", + "id": 5, + "license": "GPL-2.0", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 3, + "literals": + [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "35:22:1" + }, + { + "absolutePath": "/lib/L.sol", + "file": "../L.sol", + "id": 4, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "src": "58:18:1", + "symbolAliases": [], + "unitAlias": "" + } + ], + "src": "35:41:1" + }, + "id": 1 + } + } +} diff --git a/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json b/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json index a42a10aed4..a36c59fffb 100644 --- a/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json +++ b/test/libsolidity/ASTJSON/not_existing_import_parseOnly.json @@ -5,6 +5,7 @@ "nodes": [ { + "absolutePath": "notexisting.sol", "file": "notexisting.sol", "id": 1, "nameLocation": "28:11:1", From 7ccdbd5b08e51b43eef791f0495fee215bc0c791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 11:58:47 +0200 Subject: [PATCH 0098/1748] Use consistent syntax for Bash function declarations --- scripts/check_style.sh | 2 +- scripts/ci/build_ossfuzz.sh | 4 ++-- scripts/ci/docker_upgrade.sh | 6 +++-- scripts/common.sh | 24 +++++++++---------- scripts/common_cmdline.sh | 3 ++- scripts/docker_deploy_manual.sh | 2 +- scripts/docs_version_pragma_check.sh | 8 +++---- .../bytecode_reports_for_modified_binaries.sh | 6 ++--- scripts/soltest.sh | 3 ++- scripts/test_antlr_grammar.sh | 6 ++--- scripts/tests.sh | 3 ++- .../docker-scripts/rebuild_tags.sh | 9 ++++--- scripts/yul_coverage.sh | 6 +++-- test/cmdlineTests.sh | 4 ++-- test/docsCodeStyle.sh | 8 +++---- test/externalTests/common.sh | 6 +++-- test/stopAfterParseTests.sh | 2 +- 17 files changed, 57 insertions(+), 45 deletions(-) diff --git a/scripts/check_style.sh b/scripts/check_style.sh index 78b0aa23c2..601981b5cb 100755 --- a/scripts/check_style.sh +++ b/scripts/check_style.sh @@ -35,7 +35,7 @@ then exit 1 fi -function preparedGrep() +function preparedGrep { git grep -nIE "$1" -- '*.h' '*.cpp' | grep -v "${EXCLUDE_FILES_JOINED}" return $? diff --git a/scripts/ci/build_ossfuzz.sh b/scripts/ci/build_ossfuzz.sh index f208c9b7fe..1240b6877f 100755 --- a/scripts/ci/build_ossfuzz.sh +++ b/scripts/ci/build_ossfuzz.sh @@ -5,7 +5,7 @@ ROOTDIR="/root/project" BUILDDIR="${ROOTDIR}/build" mkdir -p "${BUILDDIR}" && mkdir -p "$BUILDDIR/deps" -generate_protobuf_bindings() +function generate_protobuf_bindings { cd "${ROOTDIR}"/test/tools/ossfuzz # Generate protobuf C++ bindings @@ -15,7 +15,7 @@ generate_protobuf_bindings() done } -build_fuzzers() +function build_fuzzers { cd "${BUILDDIR}" cmake .. -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" \ diff --git a/scripts/ci/docker_upgrade.sh b/scripts/ci/docker_upgrade.sh index 29e80354a1..a9c7acaf28 100755 --- a/scripts/ci/docker_upgrade.sh +++ b/scripts/ci/docker_upgrade.sh @@ -1,11 +1,13 @@ #!/usr/bin/env bash set -e -function error() { +function error +{ echo >&2 "ERROR: ${1} Aborting." && false } -function warning() { +function warning +{ echo >&2 "WARNING: ${1}" } diff --git a/scripts/common.sh b/scripts/common.sh index 6d9b0a3ba8..3e40754a61 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -29,15 +29,15 @@ _initial_work_dir=$(pwd) if [ "$CIRCLECI" ] then export TERM="${TERM:-xterm}" - function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput setaf 7)"; } - function printError() { >&2 echo "$(tput setaf 1)$1$(tput setaf 7)"; } - function printWarning() { >&2 echo "$(tput setaf 11)$1$(tput setaf 7)"; } - function printLog() { echo "$(tput setaf 3)$1$(tput setaf 7)"; } + function printTask { echo "$(tput bold)$(tput setaf 2)$1$(tput setaf 7)"; } + function printError { >&2 echo "$(tput setaf 1)$1$(tput setaf 7)"; } + function printWarning { >&2 echo "$(tput setaf 11)$1$(tput setaf 7)"; } + function printLog { echo "$(tput setaf 3)$1$(tput setaf 7)"; } else - function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; } - function printError() { >&2 echo "$(tput setaf 1)$1$(tput sgr0)"; } - function printWarning() { >&2 echo "$(tput setaf 11)$1$(tput sgr0)"; } - function printLog() { echo "$(tput setaf 3)$1$(tput sgr0)"; } + function printTask { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; } + function printError { >&2 echo "$(tput setaf 1)$1$(tput sgr0)"; } + function printWarning { >&2 echo "$(tput setaf 11)$1$(tput sgr0)"; } + function printLog { echo "$(tput setaf 3)$1$(tput sgr0)"; } fi function printStackTrace @@ -78,7 +78,7 @@ function printStackTrace done } -function fail() +function fail { printError "$@" @@ -86,7 +86,7 @@ function fail() return 1 } -function assertFail() +function assertFail { printError "" (( $# == 0 )) && printError "Assertion failed." @@ -97,7 +97,7 @@ function assertFail() exit 2 } -function msg_on_error() +function msg_on_error { local error_message local no_stdout=false @@ -171,7 +171,7 @@ function msg_on_error() fi } -safe_kill() +function safe_kill { local PID=${1} local NAME=${2:-${1}} diff --git a/scripts/common_cmdline.sh b/scripts/common_cmdline.sh index 15d93f562c..3efeadc03d 100644 --- a/scripts/common_cmdline.sh +++ b/scripts/common_cmdline.sh @@ -22,7 +22,8 @@ YULARGS=(--strict-assembly) FULLARGS=(--optimize --combined-json "abi,asm,ast,bin,bin-runtime,devdoc,hashes,metadata,opcodes,srcmap,srcmap-runtime,userdoc") OLDARGS=(--optimize --combined-json "abi,asm,ast,bin,bin-runtime,devdoc,interface,metadata,opcodes,srcmap,srcmap-runtime,userdoc") -function compileFull() + +function compileFull { local expected_exit_code=0 local expect_output='none' diff --git a/scripts/docker_deploy_manual.sh b/scripts/docker_deploy_manual.sh index 18d2228d0e..12d3e5ff45 100755 --- a/scripts/docker_deploy_manual.sh +++ b/scripts/docker_deploy_manual.sh @@ -28,7 +28,7 @@ else date -u +"nightly.%Y.%-m.%-d" > prerelease.txt fi -tag_and_push() +function tag_and_push { docker tag "$image:$1" "$image:$2" docker push "$image:$2" diff --git a/scripts/docs_version_pragma_check.sh b/scripts/docs_version_pragma_check.sh index d16645da8e..d56bed3a19 100755 --- a/scripts/docs_version_pragma_check.sh +++ b/scripts/docs_version_pragma_check.sh @@ -36,7 +36,7 @@ source "${REPO_ROOT}/scripts/common_cmdline.sh" developmentVersion=$("$REPO_ROOT/scripts/get_version.sh") -function versionGreater() +function versionGreater { v1=$1 v2=$2 @@ -58,7 +58,7 @@ function versionGreater() return 1 } -function versionEqual() +function versionEqual { if [[ "$1" == "$2" ]] then @@ -67,7 +67,7 @@ function versionEqual() return 1 } -function getAllAvailableVersions() +function getAllAvailableVersions { allVersions=() local allListedVersions @@ -85,7 +85,7 @@ function getAllAvailableVersions() done } -function findMinimalVersion() +function findMinimalVersion { local f=$1 local greater=false diff --git a/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh b/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh index 3401c127f7..69d6a34d01 100755 --- a/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh +++ b/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh @@ -50,14 +50,14 @@ # FIXME: Can't use set -u because the old Bash on macOS treats empty arrays as unbound variables set -eo pipefail -die() +function die { # shellcheck disable=SC2059 >&2 printf "ERROR: $1\n" "${@:2}" exit 1 } -get_reported_solc_version() +function get_reported_solc_version { local solc_binary="$1" @@ -70,7 +70,7 @@ get_reported_solc_version() echo "$version_banner" | tail -n 1 | sed -n -E 's/^Version: (.*)$/\1/p' } -validate_reported_version() +function validate_reported_version { local reported_version="$1" local expected_version_and_commit="$2" diff --git a/scripts/soltest.sh b/scripts/soltest.sh index e9b6de979f..e15aeb9bf5 100755 --- a/scripts/soltest.sh +++ b/scripts/soltest.sh @@ -8,7 +8,8 @@ BOOST_OPTIONS=() SOLTEST_OPTIONS=() SOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build} -usage() { +function usage +{ echo 2>&1 " Usage: $0 [options] [soltest-options] Runs BOOST C++ unit test program, soltest. diff --git a/scripts/test_antlr_grammar.sh b/scripts/test_antlr_grammar.sh index 97aaa3b933..5745f01be3 100755 --- a/scripts/test_antlr_grammar.sh +++ b/scripts/test_antlr_grammar.sh @@ -20,7 +20,7 @@ SGR_BLUE="\033[34m" vt_cursor_up() { echo -ne "\033[A"; } vt_cursor_begin_of_line() { echo -ne "\r"; } -download_antlr4() +function download_antlr4 { if [[ ! -e "$ANTLR_JAR" ]] then @@ -28,7 +28,7 @@ download_antlr4() fi } -prepare_workdir() +function prepare_workdir { mkdir -p "${ROOT_DIR}/build/deps" mkdir -p "${WORKDIR}" @@ -51,7 +51,7 @@ javac -classpath "${ANTLR_JAR}" "${WORKDIR}/src/"*.java -d "${WORKDIR}/target/" # Run tests failed_count=0 -test_file() +function test_file { local SOL_FILE SOL_FILE="$(${READLINK} -m "${1}")" diff --git a/scripts/tests.sh b/scripts/tests.sh index 964d006680..029be16291 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -38,7 +38,8 @@ source "${REPO_ROOT}/scripts/common.sh" WORKDIR=$(mktemp -d) CMDLINE_PID= -cleanup() { +function cleanup +{ # ensure failing commands don't cause termination during cleanup (especially within safe_kill) set +e diff --git a/scripts/wasm-rebuild/docker-scripts/rebuild_tags.sh b/scripts/wasm-rebuild/docker-scripts/rebuild_tags.sh index 18c922c06d..eaca0c7307 100755 --- a/scripts/wasm-rebuild/docker-scripts/rebuild_tags.sh +++ b/scripts/wasm-rebuild/docker-scripts/rebuild_tags.sh @@ -38,7 +38,8 @@ ORANGE='\033[0;33m' CYAN='\033[0;36m' RESET='\033[0m' -function generate_bytecode_report() { +function generate_bytecode_report +{ rm -rf /tmp/report.txt local EXIT_STATUS @@ -74,7 +75,8 @@ function generate_bytecode_report() { echo -e "${RED}FAILURE${RESET}" fi } -function clean_git_checkout() { +function clean_git_checkout +{ git submodule deinit --all -q git reset --hard HEAD --quiet git clean -f -d -x --quiet @@ -82,7 +84,8 @@ function clean_git_checkout() { git submodule init -q git submodule update -q } -function process_tag() { +function process_tag +{ local TAG=$1 cd /src # Checkout the historic commit instead of the tag directly. diff --git a/scripts/yul_coverage.sh b/scripts/yul_coverage.sh index 02b9a04764..b2b16675c5 100755 --- a/scripts/yul_coverage.sh +++ b/scripts/yul_coverage.sh @@ -83,7 +83,8 @@ for arg in "$@"; do esac done -show_output_if() { +function show_output_if +{ local VAR=${1} if [ -n "${VAR}" ]; then echo "${SOL_FILE}" @@ -102,7 +103,8 @@ if [ ! -f "${SOLC}" ]; then exit 1 fi -test_file() { +function test_file +{ local SOL_FILE local OUTPUT SOL_FILE=${1} diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 59c29ca453..2076eb993e 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -154,7 +154,7 @@ function ask_expectation_update # General helper function for testing SOLC behaviour, based on file name, compile opts, exit code, stdout and stderr. # An failure is expected. -function test_solc_behaviour() +function test_solc_behaviour { local filename="${1}" local solc_args @@ -288,7 +288,7 @@ EOF } -function test_solc_assembly_output() +function test_solc_assembly_output { local input="${1}" local expected="${2}" diff --git a/test/docsCodeStyle.sh b/test/docsCodeStyle.sh index 33b787e25f..675828d7e1 100755 --- a/test/docsCodeStyle.sh +++ b/test/docsCodeStyle.sh @@ -10,11 +10,11 @@ REPO_ROOT=$(cd "$(dirname "$0")/.." && pwd) if [ "$CIRCLECI" ] then - function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput setaf 7)"; } - function printError() { echo "$(tput setaf 1)$1$(tput setaf 7)"; } + function printTask { echo "$(tput bold)$(tput setaf 2)$1$(tput setaf 7)"; } + function printError { echo "$(tput setaf 1)$1$(tput setaf 7)"; } else - function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; } - function printError() { echo "$(tput setaf 1)$1$(tput sgr0)"; } + function printTask { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; } + function printError { echo "$(tput setaf 1)$1$(tput sgr0)"; } fi printTask "Checking docs examples style" diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index f015b5fd76..4e28d233f2 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -187,7 +187,8 @@ function run_test $test_fn } -function optimizer_settings_for_level { +function optimizer_settings_for_level +{ local level="$1" case "$level" in @@ -201,7 +202,8 @@ function optimizer_settings_for_level { esac } -function truffle_compiler_settings { +function truffle_compiler_settings +{ local solc_path="$1" local level="$2" local evm_version="$3" diff --git a/test/stopAfterParseTests.sh b/test/stopAfterParseTests.sh index a100146b06..503c435792 100755 --- a/test/stopAfterParseTests.sh +++ b/test/stopAfterParseTests.sh @@ -15,7 +15,7 @@ FILETMP=$(mktemp -d) cd "$FILETMP" || exit 1 -function testFile() +function testFile { set +e ALLOUTPUT=$($SOLC --combined-json ast --pretty-json "$@" --stop-after parsing 2>&1) From b57c0a0b81253b2bc484df8b9fd01847d1663cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 25 Oct 2021 14:29:43 +0200 Subject: [PATCH 0099/1748] externalTests: Refactor to be more explicit and easier to adjust for special cases --- test/externalTests/colony.sh | 25 ++++++-- test/externalTests/common.sh | 90 +++++++++++---------------- test/externalTests/ens.sh | 23 +++++-- test/externalTests/gnosis-v2.sh | 22 +++++-- test/externalTests/gnosis.sh | 23 +++++-- test/externalTests/solc-js/solc-js.sh | 1 - test/externalTests/zeppelin.sh | 28 ++++++--- 7 files changed, 127 insertions(+), 85 deletions(-) diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index ef06f1d7b0..43b452ec4d 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -27,24 +27,37 @@ source test/externalTests/common.sh verify_input "$1" SOLJSON="$1" -function install_fn { yarn; git submodule update --init; } function compile_fn { yarn run provision:token:contracts; } function test_fn { yarn run test:contracts; } function colony_test { - OPTIMIZER_LEVEL=3 - CONFIG="truffle.js" + local repo="https://github.com/solidity-external-tests/colonyNetwork.git" + local branch=develop_080 + local config_file="truffle.js" + local min_optimizer_level=3 + local max_optimizer_level=3 - truffle_setup "$SOLJSON" https://github.com/solidity-external-tests/colonyNetwork.git develop_080 - run_install "$SOLJSON" install_fn + setup_solcjs "$DIR" "$SOLJSON" + download_project "$repo" "$branch" "$DIR" + + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + yarn + git submodule update --init cd lib rm -Rf dappsys git clone https://github.com/solidity-external-tests/dappsys-monolithic.git -b master_080 dappsys cd .. - truffle_run_test "$SOLJSON" compile_fn test_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + + for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + done } external_test ColonyNetworks colony_test diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 4e28d233f2..8f9b5d39ef 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -22,6 +22,8 @@ set -e # Requires "${REPO_ROOT}/scripts/common.sh" to be included before. +CURRENT_EVM_VERSION=london + function verify_input { if [ ! -f "$1" ]; then @@ -51,8 +53,8 @@ function setup_solcjs { local dir="$1" local soljson="$2" - local branch="$3" - local path="$4" + local branch="${3:-master}" + local path="${4:-solc/}" cd "$dir" printLog "Setting up solc-js..." @@ -86,16 +88,6 @@ function force_truffle_version sed -i 's/"truffle":\s*".*"/"truffle": "'"$version"'"/g' package.json } -function truffle_setup -{ - local soljson="$1" - local repo="$2" - local branch="$3" - - setup_solcjs "$DIR" "$soljson" "master" "solc" - download_project "$repo" "$branch" "$DIR" -} - function replace_version_pragmas { # Replace fixed-version pragmas (part of Consensys best practice). @@ -131,7 +123,7 @@ function force_truffle_compiler_settings local config_file="$1" local solc_path="$2" local level="$3" - local evm_version="$4" + local evm_version="${4:-"$CURRENT_EVM_VERSION"}" printLog "Forcing Truffle compiler settings..." echo "-------------------------------------" @@ -147,30 +139,18 @@ function force_truffle_compiler_settings echo "module.exports['compilers'] = $(truffle_compiler_settings "$solc_path" "$level" "$evm_version");" >> "$config_file" } -function verify_compiler_version +function truffle_verify_compiler_version { local solc_version="$1" + local full_solc_version="$2" - printLog "Verify that the correct version ($solc_version) of the compiler was used to compile the contracts..." - grep -e "$solc_version" -r build/contracts > /dev/null -} - -function clean -{ - rm -rf build || true + printLog "Verify that the correct version (${solc_version}/${full_solc_version}) of the compiler was used to compile the contracts..." + grep "$full_solc_version" --with-filename --recursive build/contracts || fail "Wrong compiler version detected." } -function run_install +function truffle_clean { - local soljson="$1" - local init_fn="$2" - printLog "Running install function..." - - replace_version_pragmas - force_truffle_solc_modules "$soljson" - force_truffle_compiler_settings "$CONFIG" "${DIR}/solc" "$OPTIMIZER_LEVEL" london - - $init_fn + rm -rf build/ } function run_test @@ -219,31 +199,35 @@ function truffle_compiler_settings echo "}" } -function truffle_run_test +function compile_and_run_test { - local soljson="$1" - local compile_fn="$2" - local test_fn="$3" + local compile_fn="$1" + local test_fn="$2" + local verify_fn="$3" - replace_version_pragmas - force_truffle_solc_modules "$soljson" + printLog "Running compile function..." + $compile_fn + $verify_fn "$SOLCVERSION_SHORT" "$SOLCVERSION" - for level in $(seq "$OPTIMIZER_LEVEL" 3) - do - clean - force_truffle_compiler_settings "$CONFIG" "${DIR}/solc" "$level" london - - printLog "Running compile function..." - $compile_fn - verify_compiler_version "$SOLCVERSION" - - if [[ "$COMPILE_ONLY" == 1 ]]; then - printLog "Skipping test function..." - else - printLog "Running test function..." - $test_fn - fi - done + if [[ "$COMPILE_ONLY" == 1 ]]; then + printLog "Skipping test function..." + else + printLog "Running test function..." + $test_fn + fi +} + +function truffle_run_test +{ + local config_file="$1" + local solc_path="$2" + local optimizer_level="$3" + local compile_fn="$4" + local test_fn="$5" + + truffle_clean + force_truffle_compiler_settings "$config_file" "$solc_path" "$optimizer_level" + compile_and_run_test compile_fn test_fn truffle_verify_compiler_version } function external_test diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index e3bdb229a5..f6a17d6a8f 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -27,16 +27,19 @@ source test/externalTests/common.sh verify_input "$1" export SOLJSON="$1" -function install_fn { npm install; } function compile_fn { npx truffle compile; } function test_fn { npm run test; } function ens_test { - export OPTIMIZER_LEVEL=1 - export CONFIG="truffle-config.js" + local repo="https://github.com/ensdomains/ens.git" + local branch=master + local config_file="truffle-config.js" + local min_optimizer_level=1 + local max_optimizer_level=3 - truffle_setup "$SOLJSON" https://github.com/ensdomains/ens.git master + setup_solcjs "$DIR" "$SOLJSON" + download_project "$repo" "$branch" "$DIR" # Use latest Truffle. Older versions crash on the output from 0.8.0. force_truffle_version ^5.1.55 @@ -44,9 +47,17 @@ function ens_test # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json rm -f package-lock.json - run_install "$SOLJSON" install_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + npm install - truffle_run_test "$SOLJSON" compile_fn test_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + + for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + done } external_test Ens ens_test diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 338b2418f6..f3aab6d34d 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -33,10 +33,14 @@ function test_fn { npm test; } function gnosis_safe_test { - OPTIMIZER_LEVEL=2 - CONFIG="truffle-config.js" + local repo="https://github.com/solidity-external-tests/safe-contracts.git" + local branch=v2_080 + local config_file="truffle-config.js" + local min_optimizer_level=2 + local max_optimizer_level=3 - truffle_setup "$SOLJSON" https://github.com/solidity-external-tests/safe-contracts.git v2_080 + setup_solcjs "$DIR" "$SOLJSON" + download_project "$repo" "$branch" "$DIR" sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json sed -i -E 's|"@gnosis.pm/util-contracts": "[^"]+"|"@gnosis.pm/util-contracts": "github:solidity-external-tests/util-contracts#solc-7_080"|g' package.json @@ -44,9 +48,17 @@ function gnosis_safe_test # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json rm -f package-lock.json - run_install "$SOLJSON" install_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + npm install --package-lock - truffle_run_test "$SOLJSON" compile_fn test_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + + for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + done } external_test Gnosis-Safe gnosis_safe_test diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index a8a50782d5..7507a1b48e 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -27,25 +27,36 @@ source test/externalTests/common.sh verify_input "$1" SOLJSON="$1" -function install_fn { npm install --package-lock; } function compile_fn { npx truffle compile; } function test_fn { npm test; } function gnosis_safe_test { - OPTIMIZER_LEVEL=2 - CONFIG="truffle-config.js" + local repo="https://github.com/solidity-external-tests/safe-contracts.git" + local branch=development_080 + local config_file="truffle-config.js" + local min_optimizer_level=2 + local max_optimizer_level=3 - truffle_setup "$SOLJSON" https://github.com/solidity-external-tests/safe-contracts.git development_080 + setup_solcjs "$DIR" "$SOLJSON" + download_project "$repo" "$branch" "$DIR" sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json rm -f package-lock.json - run_install "$SOLJSON" install_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + npm install --package-lock - truffle_run_test "$SOLJSON" compile_fn test_fn + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + + for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + done } external_test Gnosis-Safe gnosis_safe_test diff --git a/test/externalTests/solc-js/solc-js.sh b/test/externalTests/solc-js/solc-js.sh index fa0d7ccee3..a3b24db9ec 100755 --- a/test/externalTests/solc-js/solc-js.sh +++ b/test/externalTests/solc-js/solc-js.sh @@ -28,7 +28,6 @@ verify_version_input "$1" "$2" SOLJSON="$1" VERSION="$2" -function install_fn { echo "Nothing to install."; } function compile_fn { echo "Nothing to compile."; } function test_fn { npm test; } diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index ca90d46f44..f665c9d621 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -27,19 +27,31 @@ source test/externalTests/common.sh verify_input "$1" SOLJSON="$1" -function install_fn { npm install; } function compile_fn { npx truffle compile; } function test_fn { npm run test; } function zeppelin_test { - OPTIMIZER_LEVEL=1 - CONFIG="truffle-config.js" - - truffle_setup "$SOLJSON" https://github.com/OpenZeppelin/openzeppelin-contracts.git master - run_install "$SOLJSON" install_fn - - truffle_run_test "$SOLJSON" compile_fn test_fn + local repo="https://github.com/OpenZeppelin/openzeppelin-contracts.git" + local branch=master + local config_file="truffle-config.js" + local min_optimizer_level=1 + local max_optimizer_level=3 + + setup_solcjs "$DIR" "$SOLJSON" + download_project "$repo" "$branch" "$DIR" + + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + npm install + + replace_version_pragmas + force_truffle_solc_modules "$SOLJSON" + + for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + done } external_test Zeppelin zeppelin_test From 7b7cc081db7d252dbe6a805c304219cfe399c0e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Oct 2021 15:00:34 +0200 Subject: [PATCH 0100/1748] externalTests: Helper for neutralizing package locks --- test/externalTests/common.sh | 8 ++++++++ test/externalTests/ens.sh | 4 +--- test/externalTests/gnosis-v2.sh | 4 +--- test/externalTests/gnosis.sh | 4 +--- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 8f9b5d39ef..038036159e 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -96,6 +96,14 @@ function replace_version_pragmas find . test -name '*.sol' -type f -print0 | xargs -0 sed -i -E -e 's/pragma solidity [^;]+;/pragma solidity >=0.0;/' } +function neutralize_package_lock +{ + # Remove lock files (if they exist) to prevent them from overriding our changes in package.json + printLog "Removing package lock files..." + rm --force --verbose yarn.lock + rm --force --verbose package-lock.json +} + function force_truffle_solc_modules { local soljson="$1" diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index f6a17d6a8f..de49e1ee3c 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -44,9 +44,7 @@ function ens_test # Use latest Truffle. Older versions crash on the output from 0.8.0. force_truffle_version ^5.1.55 - # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json - rm -f package-lock.json - + neutralize_package_lock replace_version_pragmas force_truffle_solc_modules "$SOLJSON" force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index f3aab6d34d..6e9c5e02b1 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -45,9 +45,7 @@ function gnosis_safe_test sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json sed -i -E 's|"@gnosis.pm/util-contracts": "[^"]+"|"@gnosis.pm/util-contracts": "github:solidity-external-tests/util-contracts#solc-7_080"|g' package.json - # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json - rm -f package-lock.json - + neutralize_package_lock replace_version_pragmas force_truffle_solc_modules "$SOLJSON" force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 7507a1b48e..5730b34956 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -43,9 +43,7 @@ function gnosis_safe_test sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json - # Remove the lock file (if it exists) to prevent it from overriding our changes in package.json - rm -f package-lock.json - + neutralize_package_lock replace_version_pragmas force_truffle_solc_modules "$SOLJSON" force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" From c090ff9d833a113113af8db75f174daddae7c281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Oct 2021 15:39:19 +0200 Subject: [PATCH 0101/1748] externalTests: Neutralize npm hooks instead of replacing pragmas twice - This also has the nice effect of stopping projects from trying to compile contracts during installation --- test/externalTests/colony.sh | 3 +-- test/externalTests/common.sh | 8 ++++++++ test/externalTests/ens.sh | 3 +-- test/externalTests/gnosis-v2.sh | 3 +-- test/externalTests/gnosis.sh | 3 +-- test/externalTests/zeppelin.sh | 3 +-- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 43b452ec4d..33526f58e8 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -41,8 +41,7 @@ function colony_test setup_solcjs "$DIR" "$SOLJSON" download_project "$repo" "$branch" "$DIR" - replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" yarn git submodule update --init diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 038036159e..cee846a5b9 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -104,6 +104,14 @@ function neutralize_package_lock rm --force --verbose package-lock.json } +function neutralize_package_json_hooks +{ + printLog "Disabling package.json hooks..." + [[ -f package.json ]] || fail "package.json not found" + sed -i 's|"prepublish": *".*"|"prepublish": ""|g' package.json + sed -i 's|"prepare": *".*"|"prepare": ""|g' package.json +} + function force_truffle_solc_modules { local soljson="$1" diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index de49e1ee3c..5ec6306588 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -45,8 +45,7 @@ function ens_test force_truffle_version ^5.1.55 neutralize_package_lock - replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" npm install diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 6e9c5e02b1..e8593aa610 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -46,8 +46,7 @@ function gnosis_safe_test sed -i -E 's|"@gnosis.pm/util-contracts": "[^"]+"|"@gnosis.pm/util-contracts": "github:solidity-external-tests/util-contracts#solc-7_080"|g' package.json neutralize_package_lock - replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" npm install --package-lock diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 5730b34956..95a1ecd497 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -44,8 +44,7 @@ function gnosis_safe_test sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json neutralize_package_lock - replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" npm install --package-lock diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index f665c9d621..750be3229c 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -41,8 +41,7 @@ function zeppelin_test setup_solcjs "$DIR" "$SOLJSON" download_project "$repo" "$branch" "$DIR" - replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" npm install From 0745279f1562d1d7efb2707c74d046f129c74c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 27 Oct 2021 16:26:52 +0200 Subject: [PATCH 0102/1748] externalTests: Generalize force_truffle_solc_modules and make it use symlinks instead of redownloading solc-js --- test/externalTests/colony.sh | 2 +- test/externalTests/common.sh | 29 +++++++++++++---------------- test/externalTests/ens.sh | 2 +- test/externalTests/gnosis-v2.sh | 2 +- test/externalTests/gnosis.sh | 2 +- test/externalTests/zeppelin.sh | 2 +- 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 33526f58e8..e32385af65 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -52,7 +52,7 @@ function colony_test cd .. replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + force_solc_modules "${DIR}/solc" for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index cee846a5b9..dbda3c3f46 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -112,25 +112,22 @@ function neutralize_package_json_hooks sed -i 's|"prepare": *".*"|"prepare": ""|g' package.json } -function force_truffle_solc_modules +function force_solc_modules { - local soljson="$1" + local custom_solcjs_path="${1:-solc/}" + + [[ -d node_modules/ ]] || assertFail - # Replace solc package by v0.5.0 and then overwrite with current version. - printLog "Forcing solc version for all Truffle modules..." - for d in node_modules node_modules/truffle/node_modules + printLog "Replacing all installed solc-js with a link to the latest version..." + soljson_binaries=$(find node_modules -type f -path "*/solc/soljson.js") + for soljson_binary in $soljson_binaries do - ( - if [ -d "$d" ]; then - cd $d - rm -rf solc - git clone --depth 1 -b master https://github.com/ethereum/solc-js.git solc - cp "$soljson" solc/soljson.js - - cd solc - npm install - fi - ) + local solc_module_path + solc_module_path=$(dirname "$soljson_binary") + + printLog "Found and replaced solc-js in $solc_module_path" + rm -r "$solc_module_path" + ln -s "$custom_solcjs_path" "$solc_module_path" done } diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index 5ec6306588..bbdc573e21 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -50,7 +50,7 @@ function ens_test npm install replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + force_solc_modules "${DIR}/solc" for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index e8593aa610..d92bcc1868 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -51,7 +51,7 @@ function gnosis_safe_test npm install --package-lock replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + force_solc_modules "${DIR}/solc" for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 95a1ecd497..b6d9ab0bcb 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -49,7 +49,7 @@ function gnosis_safe_test npm install --package-lock replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + force_solc_modules "${DIR}/solc" for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 750be3229c..1e23bb7ae5 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -46,7 +46,7 @@ function zeppelin_test npm install replace_version_pragmas - force_truffle_solc_modules "$SOLJSON" + force_solc_modules "${DIR}/solc" for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn From df85d2640652060ba967c8e4ba00d8116cb1a447 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 8 Nov 2021 15:56:09 +0100 Subject: [PATCH 0103/1748] Update ir-breaking-changes and make it visible. --- docs/conf.py | 2 +- docs/index.rst | 1 + docs/{ir => }/ir-breaking-changes.rst | 54 ++++++++++++++++++++++----- 3 files changed, 46 insertions(+), 11 deletions(-) rename docs/{ir => }/ir-breaking-changes.rst (82%) diff --git a/docs/conf.py b/docs/conf.py index b75eb966da..5fa2e6ab5d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -91,7 +91,7 @@ def setup(sphinx): # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build', 'contracts', 'types', 'examples', 'grammar', 'ir'] +exclude_patterns = ['_build', 'contracts', 'types', 'examples', 'grammar'] # The reST default role (used for this markup: `text`) to use for all # documents. diff --git a/docs/index.rst b/docs/index.rst index 476cd86117..60b3d61fac 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -136,6 +136,7 @@ Contents using-the-compiler.rst analysing-compilation-output.rst + ir-breaking-changes.rst .. toctree:: :maxdepth: 2 diff --git a/docs/ir/ir-breaking-changes.rst b/docs/ir-breaking-changes.rst similarity index 82% rename from docs/ir/ir-breaking-changes.rst rename to docs/ir-breaking-changes.rst index fb971410a8..c1f6deb57f 100644 --- a/docs/ir/ir-breaking-changes.rst +++ b/docs/ir-breaking-changes.rst @@ -5,8 +5,26 @@ Solidity IR-based Codegen Changes ********************************* -This section highlights the main differences between the old and the IR-based codegen, -along with the reasoning behind the changes and how to update affected code. +Solidity can generate EVM bytecode in two different ways: +Either directly from Solidity to EVM opcodes ("old codegen") or through +an intermediate representation ("IR") in Yul ("new codegen" or "IR-based codegen"). + +The IR-based code generator was introduced with an aim to not only allow +code generation to be more transparent and auditable but also +to enable more powerful optimization passes that span across functions. + +Currently, the IR-based code generator is still marked experimental, +but it supports all language features and has received a lot of testing, +so we consider it almost ready for production use. + +You can enable it on the command line using ``--experimental-via-ir`` +or with the option ``{"viaIR": true}`` in standard-json and we +encourage everyone to try it out! + +For several reasons, there are tiny semantic differences between the old +and the IR-based code generator, mostly in areas where we would not +expect people to rely on this behaviour anyway. +This section highlights the main differences between the old and the IR-based codegen. Semantic Only Changes ===================== @@ -14,8 +32,13 @@ Semantic Only Changes This section lists the changes that are semantic-only, thus potentially hiding new and different behavior in existing code. -- When storage structs are deleted, every storage slot that contains a member of the struct is set to zero entirely. Formally, padding space was left untouched. - Consequently, if the padding space within a struct is used to store data (e.g. in the context of a contract upgrade), you have to be aware that ``delete`` will now also clear the added member (while it wouldn't have been cleared in the past). +- When storage structs are deleted, every storage slot that contains + a member of the struct is set to zero entirely. Formerly, padding space + was left untouched. + Consequently, if the padding space within a struct is used to store data + (e.g. in the context of a contract upgrade), you have to be aware that + ``delete`` will now also clear the added member (while it wouldn't + have been cleared in the past). .. code-block:: solidity @@ -132,7 +155,10 @@ This causes differences in some contracts, for example: Previously, ``y`` would be set to 0. This is due to the fact that we would first initialize state variables: First, ``x`` is set to 0, and when initializing ``y``, ``f()`` would return 0 causing ``y`` to be 0 as well. With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, then call A's constructor which sets ``x`` to 42. Finally, when initializing ``y``, ``f()`` returns 42 causing ``y`` to be 42. -- Copying ``bytes`` arrays from memory to storage is implemented in a different way. The old code generator always copies full words, while the new one cuts the byte array after its end. The old behaviour can lead to dirty data being copied after the end of the array (but still in the same storage slot). +- Copying ``bytes`` arrays from memory to storage is implemented in a different way. + The old code generator always copies full words, while the new one cuts the byte + array after its end. The old behaviour can lead to dirty data being copied after + the end of the array (but still in the same storage slot). This causes differences in some contracts, for example: .. code-block:: solidity @@ -155,8 +181,10 @@ This causes differences in some contracts, for example: } } - Previously ``f()`` would return ``0x6465616462656566313564656164000000000000000000000000000000000010`` (it has correct length, and correct first 8 elements, but then it contains dirty data which was set via assembly). - Now it is returning ``0x6465616462656566000000000000000000000000000000000000000000000010`` (it has correct length, and correct elements, but does not contain superfluous data). + Previously ``f()`` would return ``0x6465616462656566313564656164000000000000000000000000000000000010`` + (it has correct length, and correct first 8 elements, but then it contains dirty data which was set via assembly). + Now it is returning ``0x6465616462656566000000000000000000000000000000000000000000000010`` (it has + correct length, and correct elements, but does not contain superfluous data). .. index:: ! evaluation order; expression @@ -183,7 +211,8 @@ This causes differences in some contracts, for example: .. index:: ! evaluation order; function arguments - On the other hand, function argument expressions are evaluated in the same order by both code generators with the exception of the global functions ``addmod`` and ``mulmod``. + On the other hand, function argument expressions are evaluated in the same order + by both code generators with the exception of the global functions ``addmod`` and ``mulmod``. For example: .. code-block:: solidity @@ -227,11 +256,15 @@ This causes differences in some contracts, for example: - Old code generator: ``aMod = 0`` and ``mMod = 2`` - New code generator: ``aMod = 4`` and ``mMod = 0`` -- The new code generator imposes a hard limit of ``type(uint64).max`` (``0xffffffffffffffff``) for the free memory pointer. Allocations that would increase its value beyond this limit revert. The old code generator does not have this limit. +- The new code generator imposes a hard limit of ``type(uint64).max`` + (``0xffffffffffffffff``) for the free memory pointer. Allocations that would + increase its value beyond this limit revert. The old code generator does not + have this limit. For example: .. code-block:: solidity + :force: // SPDX-License-Identifier: GPL-3.0 pragma solidity >0.8.0; @@ -264,7 +297,7 @@ The old code generator uses code offsets or tags for values of internal function these offsets are different at construction time and after deployment and the values can cross this border via storage. Because of that, both offsets are encoded at construction time into the same value (into different bytes). -In the new code generator, function pointers use the AST IDs of the functions as values. Since calls via jumps are not possible, +In the new code generator, function pointers use internal IDs that are allocated in sequence. Since calls via jumps are not possible, calls through function pointers always have to use an internal dispatch function that uses the ``switch`` statement to select the right function. @@ -280,6 +313,7 @@ Cleanup The old code generator only performs cleanup before an operation whose result could be affected by the values of the dirty bits. The new code generator performs cleanup after any operation that can result in dirty bits. +The hope is that the optimizer will be powerful enough to eliminate redundant cleanup operations. For example: From 45c9dbe1743c0e5cd5a3f42a97ce7afda977ff5a Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 8 Nov 2021 13:06:20 +0100 Subject: [PATCH 0104/1748] Sort changelog and set release date. --- Changelog.md | 12 ++++++------ docs/bugs_by_version.json | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Changelog.md b/Changelog.md index 174c59356c..ee463b25cd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,4 @@ -### 0.8.10 (unreleased) +### 0.8.10 (2021-11-09) Language Features: * Inline Assembly: Support ``.address`` and ``.selector`` on external function pointers to access their address and function selector. @@ -28,23 +28,23 @@ Bugfixes: * Commandline Interface: When linking only accept exact matches for library names passed to the ``--libraries`` option. Library names not prefixed with a file name used to match any library with that name. * SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``). * SMTChecker: Fix internal error in the CHC engine when passing gas in the function options. - * TypeChecker: Fix internal error when using user defined value types in public library functions. * TypeChecker: Fix internal error when using arrays and structs with user defined value types before declaration. + * TypeChecker: Fix internal error when using user defined value types in public library functions. * TypeChecker: Improved error message for constant variables with (nested) mapping types. * Yul Assembler: Fix internal error when function names are not unique. * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts. +Important Bugfixes in Experimental Features: + * Yul IR Generator: Changes to function return variables referenced in modifier invocation arguments were not properly forwarded if there was more than one return variable. + + Build System: * Pass linker-only emscripten options only when linking. * Remove obsolete compatibility workaround for emscripten builds. * Update emscripten to version 2.0.33. -Important Bugfixes in Experimental Features: - * Yul IR Generator: Changes to function return variables referenced in modifier invocation arguments were not properly forwarded if there was more than one return variable. - - ### 0.8.9 (2021-09-29) Important Bugfixes: diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 4324b8339e..6385af1707 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1544,6 +1544,10 @@ ], "released": "2021-01-27" }, + "0.8.10": { + "bugs": [], + "released": "2021-11-09" + }, "0.8.2": { "bugs": [ "SignedImmutables", From 75fd7fa93e1059aed362093191feb3e27804d465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 18:40:55 +0200 Subject: [PATCH 0105/1748] CI: Modify notification steps to be silent in PRs --- .circleci/config.yml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9e5862cab0..b7d501c719 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,7 @@ orbs: win: circleci/windows@2.2.0 commands: - gitter_notify: + gitter_notify_unless_pr: description: "Posts a notification to the main room on Gitter (if not running on a PR)." parameters: event: @@ -44,6 +44,8 @@ commands: name: "Gitter notification" when: << parameters.condition >> command: | + [[ $CI_PULL_REQUEST == "" ]] || { echo "Running on a PR - notification skipped."; exit 0; } + [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ Nightly job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." [[ "<< parameters.event >>" == "success" ]] && message=" ✅ Nightly job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." @@ -55,17 +57,17 @@ commands: --header "Authorization: Bearer ${GITTER_API_TOKEN}" \ --data "{\"text\":\"${message}\"}" - gitter_notify_failure: + gitter_notify_failure_unless_pr: description: "Posts a failure notification to the main room on Gitter (if not running on a PR)." steps: - - gitter_notify: + - gitter_notify_unless_pr: event: failure condition: on_fail - gitter_notify_success: + gitter_notify_success_unless_pr: description: "Posts a success notification to the main room on Gitter (if not running on a PR)." steps: - - gitter_notify: + - gitter_notify_unless_pr: event: success condition: on_success @@ -562,9 +564,9 @@ jobs: steps: - checkout - run: *run_build - - gitter_notify_failure - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr b_ubu_release: &b_ubu_release <<: *b_ubu @@ -650,10 +652,10 @@ jobs: git clone https://github.com/ethereum/solidity-fuzzing-corpus /tmp/solidity-fuzzing-corpus mkdir -p test_results scripts/regressions.py -o test_results - - gitter_notify_failure - - gitter_notify_success - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr + - gitter_notify_success_unless_pr b_archlinux: <<: *base_archlinux @@ -852,7 +854,7 @@ jobs: - when: condition: true <<: *steps_soltest - - gitter_notify_failure + - gitter_notify_failure_unless_pr t_ubu_ubsan_clang_cli: <<: *base_ubuntu2004_clang @@ -860,7 +862,7 @@ jobs: - when: condition: true <<: *steps_cmdline_tests - - gitter_notify_failure + - gitter_notify_failure_unless_pr t_ems_solcjs: <<: *base_ubuntu2004 @@ -940,8 +942,8 @@ jobs: - when: condition: <> steps: - - gitter_notify_failure - - gitter_notify_success + - gitter_notify_failure_unless_pr + - gitter_notify_success_unless_pr b_win: &b_win <<: *base_win_powershell From 205e05b8f12cdd754adea2850055751fb201709b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 21 Oct 2021 18:46:04 +0200 Subject: [PATCH 0106/1748] CI: Add gitter failure notifications to all jobs --- .circleci/config.yml | 60 ++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b7d501c719..72434ea15c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -189,6 +189,7 @@ defaults: - run: *run_soltest - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr - steps_soltest_all: &steps_soltest_all steps: @@ -198,6 +199,7 @@ defaults: - run: *run_soltest_all - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr - steps_cmdline_tests: &steps_cmdline_tests steps: @@ -207,6 +209,7 @@ defaults: - run: *run_cmdline_tests - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr # -------------------------------------------------------------------------- # Base Image Templates @@ -396,6 +399,7 @@ jobs: - run: name: Check spelling command: ~/.local/bin/codespell -S "*.enc,.git,Dockerfile*" -I ./scripts/codespell_whitelist.txt + - gitter_notify_failure_unless_pr chk_docs_examples: <<: *base_node_latest @@ -409,6 +413,7 @@ jobs: - run: name: Test Docs examples command: ./test/docsCodeStyle.sh + - gitter_notify_failure_unless_pr chk_coding_style: <<: *base_buildpack_focal @@ -426,6 +431,7 @@ jobs: - run: name: Check for broken symlinks command: ./scripts/check_symlinks.sh + - gitter_notify_failure_unless_pr chk_errorcodes: <<: *base_python @@ -434,6 +440,7 @@ jobs: - run: name: Check for error codes command: ./scripts/error_codes.py --check + - gitter_notify_failure_unless_pr chk_pylint: <<: *base_buildpack_focal @@ -449,6 +456,7 @@ jobs: - run: name: Linting Python Scripts command: ./scripts/pylint_all.py + - gitter_notify_failure_unless_pr chk_antlr_grammar: <<: *base_buildpack_focal @@ -460,6 +468,7 @@ jobs: - run: name: Run tests command: ./scripts/test_antlr_grammar.sh + - gitter_notify_failure_unless_pr chk_buglist: <<: *base_node_latest @@ -474,6 +483,7 @@ jobs: - run: name: Test buglist command: ./test/buglistTests.js + - gitter_notify_failure_unless_pr chk_proofs: <<: *base_buildpack_latest @@ -486,12 +496,14 @@ jobs: apt-get -qy install python3-pip pip3 install --user z3-solver - run: *run_proofs + - gitter_notify_failure_unless_pr chk_docs_pragma_min_version: <<: *base_ubuntu2004 steps: - checkout - run: *run_docs_pragma_min_version + - gitter_notify_failure_unless_pr t_ubu_pyscripts: <<: *base_ubuntu2004 @@ -500,6 +512,7 @@ jobs: - run: name: Python unit tests command: python3 test/pyscriptTests.py + - gitter_notify_failure_unless_pr t_win_pyscripts: <<: *base_win_powershell @@ -509,6 +522,7 @@ jobs: - run: name: Python unit tests command: python.exe test/pyscriptTests.py + - gitter_notify_failure_unless_pr b_ubu: &b_ubu <<: *base_ubuntu2004_xlarge @@ -519,6 +533,7 @@ jobs: - store_artifacts: *artifact_solidity_upgrade - store_artifacts: *artifact_yul_phaser - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr # x64 ASAN build, for testing for memory related bugs b_ubu_asan: &b_ubu_asan @@ -532,6 +547,7 @@ jobs: - run: *run_build - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr b_ubu_clang: &b_ubu_clang <<: *base_ubuntu2004_clang_xlarge @@ -540,6 +556,7 @@ jobs: - run: *run_build - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr b_ubu_asan_clang: &b_ubu_asan_clang <<: *base_ubuntu2004_clang @@ -553,6 +570,7 @@ jobs: - run: *run_build - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr b_ubu_ubsan_clang: &b_ubu_ubsan_clang <<: *base_ubuntu2004_clang @@ -586,6 +604,7 @@ jobs: name: strip binary command: strip build/solc/solc - store_artifacts: *artifacts_solc + - gitter_notify_failure_unless_pr b_ubu_codecov: <<: *base_ubuntu2004_xlarge @@ -597,6 +616,7 @@ jobs: - checkout - run: *run_build - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr t_ubu_codecov: <<: *base_ubuntu2004 @@ -619,6 +639,7 @@ jobs: name: "Coverage: All" command: codecov --flags all --gcov-root build - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr # Builds in C++20 mode and uses debug build in order to speed up. # Do *NOT* store any artifacts or workspace as we don't run tests on this build. @@ -631,6 +652,7 @@ jobs: steps: - checkout - run: *run_build + - gitter_notify_failure_unless_pr b_ubu_ossfuzz: &b_ubu_ossfuzz <<: *base_ubuntu1604_clang @@ -639,6 +661,7 @@ jobs: - run: *setup_prerelease_commit_hash - run: *run_build_ossfuzz - persist_to_workspace: *artifacts_executables_ossfuzz + - gitter_notify_failure_unless_pr t_ubu_ossfuzz: &t_ubu_ossfuzz <<: *base_ubuntu1604_clang @@ -671,6 +694,7 @@ jobs: - run: *run_build - store_artifacts: *artifacts_solc - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr b_osx: <<: *base_osx @@ -707,6 +731,7 @@ jobs: - build/solc/solc - build/test/soltest - build/test/tools/solfuzzer + - gitter_notify_failure_unless_pr t_osx_soltest: <<: *base_osx @@ -724,6 +749,7 @@ jobs: - run: *run_soltest - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr t_osx_cli: <<: *base_osx @@ -736,6 +762,7 @@ jobs: at: . - run: *run_cmdline_tests - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr b_ems: <<: *base_ems_xlarge @@ -756,6 +783,7 @@ jobs: paths: - soljson.js - version.txt + - gitter_notify_failure_unless_pr b_docs: <<: *base_ubuntu2004 @@ -768,6 +796,7 @@ jobs: - store_artifacts: path: docs/_build/html/ destination: docs-html + - gitter_notify_failure_unless_pr t_ubu_soltest_all: &t_ubu_soltest_all <<: *base_ubuntu2004 @@ -850,19 +879,11 @@ jobs: <<: *base_ubuntu2004_clang environment: EVM: << pipeline.parameters.evm-version >> - steps: - - when: - condition: true - <<: *steps_soltest - - gitter_notify_failure_unless_pr + <<: *steps_soltest t_ubu_ubsan_clang_cli: <<: *base_ubuntu2004_clang - steps: - - when: - condition: true - <<: *steps_cmdline_tests - - gitter_notify_failure_unless_pr + <<: *steps_cmdline_tests t_ems_solcjs: <<: *base_ubuntu2004 @@ -882,6 +903,7 @@ jobs: node --version npm --version test/externalTests/solc-js/solc-js.sh /tmp/workspace/soljson.js $(cat /tmp/workspace/version.txt) + - gitter_notify_failure_unless_pr t_ems_ext_hardhat: <<: *base_node_latest @@ -907,6 +929,7 @@ jobs: # NOTE: This is expected to work without running `yarn build` first. cd hardhat/packages/hardhat-core yarn test + - gitter_notify_failure_unless_pr t_ems_ext: parameters: @@ -918,9 +941,6 @@ jobs: nodejs_version: type: integer default: 14 - gitter_notify: - type: boolean - default: no docker: - image: circleci/node:<> environment: @@ -939,11 +959,7 @@ jobs: name: External <> tests command: | test/externalTests/<>.sh /tmp/workspace/soljson.js - - when: - condition: <> - steps: - - gitter_notify_failure_unless_pr - - gitter_notify_success_unless_pr + - gitter_notify_failure_unless_pr b_win: &b_win <<: *base_win_powershell @@ -974,6 +990,7 @@ jobs: paths: - .\solc\*\solc.exe - .\test\*\soltest.exe + - gitter_notify_failure_unless_pr b_win_release: <<: *b_win @@ -996,6 +1013,7 @@ jobs: command: .circleci/soltest.ps1 - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results + - gitter_notify_failure_unless_pr t_win_release_soltest: <<: *t_win_soltest @@ -1019,6 +1037,7 @@ jobs: paths: - bytecode-report-ubuntu-json.txt - bytecode-report-ubuntu-cli.txt + - gitter_notify_failure_unless_pr b_bytecode_osx: <<: *base_osx @@ -1039,6 +1058,7 @@ jobs: paths: - bytecode-report-osx-json.txt - bytecode-report-osx-cli.txt + - gitter_notify_failure_unless_pr b_bytecode_win: <<: *base_win_cmd @@ -1062,6 +1082,7 @@ jobs: paths: - bytecode-report-windows-json.txt - bytecode-report-windows-cli.txt + - gitter_notify_failure_unless_pr b_bytecode_ems: <<: *base_node_latest @@ -1078,6 +1099,7 @@ jobs: root: . paths: - bytecode-report-emscripten.txt + - gitter_notify_failure_unless_pr t_bytecode_compare: <<: *base_ubuntu2004 @@ -1114,6 +1136,7 @@ jobs: # NOTE: store_artifacts does not support the 'when' attribute. # Fortunately when the artifact does not exist it just says "No artifact files found" and ignores it. path: all-bytecode-reports.zip + - gitter_notify_failure_unless_pr workflows: version: 2 @@ -1284,4 +1307,3 @@ workflows: <<: *workflow_emscripten name: t_ems_test_ext_colony project: colony - gitter_notify: yes From 9fb77b139cdca101b6582e63f466771e679ecc7b Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 9 Nov 2021 13:25:00 +0100 Subject: [PATCH 0107/1748] Keep canonical form of Yul code at all times. --- libyul/optimiser/BlockFlattener.cpp | 12 ++++++++++++ libyul/optimiser/BlockFlattener.h | 2 +- libyul/optimiser/CircularReferencesPruner.cpp | 2 ++ libyul/optimiser/ExpressionJoiner.cpp | 4 +++- libyul/optimiser/FunctionGrouper.h | 2 +- libyul/optimiser/OptimizerUtilities.h | 2 ++ libyul/optimiser/Suite.cpp | 2 +- libyul/optimiser/UnusedPruner.cpp | 7 +++++++ libyul/optimiser/UnusedPruner.h | 4 +--- 9 files changed, 30 insertions(+), 7 deletions(-) diff --git a/libyul/optimiser/BlockFlattener.cpp b/libyul/optimiser/BlockFlattener.cpp index bcbe19c18d..0bb828ee5a 100644 --- a/libyul/optimiser/BlockFlattener.cpp +++ b/libyul/optimiser/BlockFlattener.cpp @@ -43,3 +43,15 @@ void BlockFlattener::operator()(Block& _block) } ); } + +void BlockFlattener::run(OptimiserStepContext&, Block& _ast) +{ + BlockFlattener flattener; + for (auto& statement: _ast.statements) + if (auto* block = get_if(&statement)) + flattener(*block); + else if (auto* function = get_if(&statement)) + flattener(function->body); + else + yulAssert(false, "BlockFlattener requires the FunctionGrouper."); +} diff --git a/libyul/optimiser/BlockFlattener.h b/libyul/optimiser/BlockFlattener.h index 87a1af7cf1..3825647de3 100644 --- a/libyul/optimiser/BlockFlattener.h +++ b/libyul/optimiser/BlockFlattener.h @@ -27,7 +27,7 @@ class BlockFlattener: public ASTModifier { public: static constexpr char const* name{"BlockFlattener"}; - static void run(OptimiserStepContext&, Block& _ast) { BlockFlattener{}(_ast); } + static void run(OptimiserStepContext&, Block& _ast); using ASTModifier::operator(); void operator()(Block& _block) override; diff --git a/libyul/optimiser/CircularReferencesPruner.cpp b/libyul/optimiser/CircularReferencesPruner.cpp index 1078779c5b..ba1fbf11da 100644 --- a/libyul/optimiser/CircularReferencesPruner.cpp +++ b/libyul/optimiser/CircularReferencesPruner.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -29,6 +30,7 @@ using namespace solidity::yul; void CircularReferencesPruner::run(OptimiserStepContext& _context, Block& _ast) { CircularReferencesPruner{_context.reservedIdentifiers}(_ast); + FunctionGrouper::run(_context, _ast); } void CircularReferencesPruner::operator()(Block& _block) diff --git a/libyul/optimiser/ExpressionJoiner.cpp b/libyul/optimiser/ExpressionJoiner.cpp index 9d1df86947..dbb684007c 100644 --- a/libyul/optimiser/ExpressionJoiner.cpp +++ b/libyul/optimiser/ExpressionJoiner.cpp @@ -22,6 +22,7 @@ #include +#include #include #include #include @@ -37,9 +38,10 @@ using namespace std; using namespace solidity; using namespace solidity::yul; -void ExpressionJoiner::run(OptimiserStepContext&, Block& _ast) +void ExpressionJoiner::run(OptimiserStepContext& _context, Block& _ast) { ExpressionJoiner{_ast}(_ast); + FunctionGrouper::run(_context, _ast); } diff --git a/libyul/optimiser/FunctionGrouper.h b/libyul/optimiser/FunctionGrouper.h index fa54099369..57ea80cac9 100644 --- a/libyul/optimiser/FunctionGrouper.h +++ b/libyul/optimiser/FunctionGrouper.h @@ -34,7 +34,7 @@ struct OptimiserStepContext; * all function definitions. * * After this step, a block is of the form - * { { I...} F... } + * { { I... } F... } * Where I are (non-function-definition) instructions and F are function definitions. */ class FunctionGrouper diff --git a/libyul/optimiser/OptimizerUtilities.h b/libyul/optimiser/OptimizerUtilities.h index 09ea9ed5a3..d80b16316a 100644 --- a/libyul/optimiser/OptimizerUtilities.h +++ b/libyul/optimiser/OptimizerUtilities.h @@ -37,6 +37,8 @@ namespace solidity::yul { /// Removes statements that are just empty blocks (non-recursive). +/// If this is run on the outermost block, the FunctionGrouper should be run afterwards to keep +/// the canonical form. void removeEmptyBlocks(Block& _block); /// Returns true if a given literal can not be used as an identifier. diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 32ea08dbe1..766cc93b90 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -118,7 +118,7 @@ void OptimiserSuite::run( // 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("hfgo", ast); + suite.runSequence("hgfo", ast); NameSimplifier::run(suite.m_context, ast); // Now the user-supplied part diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index dae4d4c6ff..cb60f9da89 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -33,6 +34,12 @@ using namespace std; using namespace solidity; using namespace solidity::yul; +void UnusedPruner::run(OptimiserStepContext& _context, Block& _ast) +{ + UnusedPruner::runUntilStabilisedOnFullAST(_context.dialect, _ast, _context.reservedIdentifiers); + FunctionGrouper::run(_context, _ast); +} + UnusedPruner::UnusedPruner( Dialect const& _dialect, Block& _ast, diff --git a/libyul/optimiser/UnusedPruner.h b/libyul/optimiser/UnusedPruner.h index af77d911af..e4587d5d72 100644 --- a/libyul/optimiser/UnusedPruner.h +++ b/libyul/optimiser/UnusedPruner.h @@ -50,9 +50,7 @@ class UnusedPruner: public ASTModifier { public: static constexpr char const* name{"UnusedPruner"}; - static void run(OptimiserStepContext& _context, Block& _ast) { - UnusedPruner::runUntilStabilisedOnFullAST(_context.dialect, _ast, _context.reservedIdentifiers); - } + static void run(OptimiserStepContext& _context, Block& _ast); using ASTModifier::operator(); From f2d9a806e0a2a2fb8560cc24d391013dcdf32553 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 9 Nov 2021 13:25:13 +0100 Subject: [PATCH 0108/1748] Document change to BlockFlattener. --- docs/internals/optimizer.rst | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index 28c342902d..d75eca4198 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -972,15 +972,19 @@ BlockFlattener ^^^^^^^^^^^^^^ This stage eliminates nested blocks by inserting the statement in the -inner block at the appropriate place in the outer block: +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. .. code-block:: yul { - let x := 2 { - let y := 3 - mstore(x, y) + let x := 2 + { + let y := 3 + mstore(x, y) + } } } @@ -989,9 +993,11 @@ is transformed to .. code-block:: yul { - let x := 2 - let y := 3 - mstore(x, y) + { + let x := 2 + let y := 3 + mstore(x, y) + } } As long as the code is disambiguated, this does not cause a problem because From 10618188dd4af178486402ca240881d633b3dbd8 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 9 Nov 2021 13:25:25 +0100 Subject: [PATCH 0109/1748] Update tests. --- .../blockFlattener/basic.yul | 28 +++++++----- .../blockFlattener/for_stmt.yul | 12 +++-- .../blockFlattener/if_stmt.yul | 24 +++++----- .../blockFlattener/many_nested_blocks.yul | 38 +++++++++------- .../blockFlattener/switch_stmt.yul | 24 +++++----- .../called_from_non_function.yul | 6 ++- .../nested_different_names.yul | 2 +- .../nested_same_name.yul | 2 +- .../circularReferencesPruner/trivial.yul | 2 +- .../expressionJoiner/if_condition.yul | 6 ++- .../expressionJoiner/muli_wrong_order3.yul | 8 ++-- .../expressionJoiner/multi.yul | 4 +- .../expressionJoiner/multi_reference.yul | 6 ++- .../expressionJoiner/multi_wrong_order.yul | 6 ++- .../expressionJoiner/multi_wrong_order2.yul | 6 ++- .../no_replacement_across_blocks.yul | 6 ++- .../no_replacement_in_loop_condition1.yul | 6 ++- .../no_replacement_in_loop_condition2.yul | 8 ++-- .../expressionJoiner/only_assignment.yul | 1 + .../expressionJoiner/reassignment.yul | 8 ++-- .../expressionJoiner/simple.yul | 4 +- .../expressionJoiner/single_wrong_order.yul | 6 ++- .../expressionJoiner/smoke.yul | 2 +- .../expressionJoiner/switch_expression.yul | 10 +++-- .../expressionJoiner/triple.yul | 4 +- .../assigned_vars_multi.yul | 6 ++- .../byte_after_shr_non_mul_of_8.yul | 2 +- .../combine_shift_and_and.yul | 8 ++-- .../combine_shift_and_and_2.yul | 44 ++++++++++--------- .../combine_shift_and_and_3.yul | 28 ++++++------ .../constant_propagation.yul | 2 +- .../expressionSimplifier/constants.yul | 2 +- .../expressionSimplifier/create2_and_mask.yul | 12 ++--- .../expressionSimplifier/create_and_mask.yul | 14 +++--- .../exp_simplifications.yul | 18 ++++---- .../expressionSimplifier/idempotency.yul | 10 +++-- .../identity_rules_complex.yul | 2 +- .../identity_rules_negative.yul | 6 ++- .../identity_rules_simple.yul | 2 +- .../including_function_calls.yul | 2 +- .../expressionSimplifier/inside_for.yul | 8 ++-- .../expressionSimplifier/invariant.yul | 2 +- .../expressionSimplifier/iszero_sub_to_eq.yul | 8 ++-- .../large_byte_access.yul | 22 +++++----- .../expressionSimplifier/mod_and_1.yul | 6 ++- .../expressionSimplifier/mod_and_2.yul | 6 ++- ...lied_function_call_different_arguments.yul | 8 ++-- ..._applied_function_call_different_names.yul | 2 +- ...ied_function_call_equality_not_movable.yul | 2 +- ...d_removes_non_constant_and_not_movable.yul | 12 ++--- .../pop_byte_shr_call.yul | 8 ++-- .../pop_byte_shr_func.yul | 6 ++- .../pop_byte_shr_func_trivial.yul | 2 +- .../expressionSimplifier/reassign.yul | 10 +++-- .../remove_redundant_shift_masking.yul | 18 ++++---- .../replace_too_large_shift.yul | 18 ++++---- .../expressionSimplifier/return_vars_zero.yul | 2 +- .../expressionSimplifier/reversed.yul | 6 ++- .../selfbalance_not_supported.yul | 4 +- .../selfbalance_split.yul | 6 ++- .../selfbalance_supported.yul | 2 +- .../side_effects_in_for_condition.yul | 6 ++- .../expressionSimplifier/smoke.yul | 2 +- .../unassigend_vars_multi.yul | 6 ++- .../expressionSimplifier/unassigned_vars.yul | 2 +- .../no_inline_into_big_function.yul | 1 + .../fullSimplify/constant_propagation.yul | 6 ++- .../fullSimplify/constants.yul | 2 +- .../fullSimplify/identity_rules_complex.yul | 2 +- .../fullSimplify/identity_rules_negative.yul | 6 ++- .../fullSimplify/identity_rules_simple.yul | 2 +- .../fullSimplify/including_function_calls.yul | 2 +- .../fullSimplify/inside_for.yul | 8 ++-- .../fullSimplify/invariant.yul | 10 +++-- .../fullSimplify/mod_and_1.yul | 6 ++- .../fullSimplify/mod_and_2.yul | 6 ++- ...lied_function_call_different_arguments.yul | 8 ++-- ..._applied_function_call_different_names.yul | 2 +- ...ied_function_call_equality_not_movable.yul | 2 +- ...d_removes_non_constant_and_not_movable.yul | 8 ++-- .../fullSimplify/operations.yul | 38 ++++++++-------- .../fullSimplify/reversed.yul | 6 ++- .../fullSimplify/signextend.yul | 6 ++- .../yulOptimizerTests/fullSimplify/smoke.yul | 2 +- .../loadResolver/double_mload.yul | 6 ++- .../double_mload_with_other_reassignment.yul | 10 +++-- .../double_mload_with_reassignment.yul | 10 +++-- .../yulOptimizerTests/loadResolver/keccak.yul | 10 +++-- .../loadResolver/keccak_crash.yul | 10 +++-- .../loadResolver/keccak_fail1.yul | 12 ++--- .../loadResolver/keccak_fail2.yul | 10 +++-- .../loadResolver/keccak_short.yul | 20 +++++---- .../loadResolver/keccak_string_literal.yul | 16 ++++--- .../loadResolver/keccak_symbolic_memory.yul | 10 +++-- .../loadResolver/keccak_with_msize.yul | 12 ++--- .../yulOptimizerTests/loadResolver/loop.yul | 16 ++++--- ...y_with_different_kinds_of_invalidation.yul | 30 +++++++------ .../loadResolver/memory_with_msize.yul | 12 ++--- .../loadResolver/merge_known_write.yul | 18 ++++---- .../merge_known_write_with_distance.yul | 14 +++--- .../merge_mload_with_known_distance.yul | 12 ++--- .../loadResolver/merge_mload_with_rewrite.yul | 14 +++--- .../merge_mload_without_rewrite.yul | 14 +++--- .../loadResolver/merge_unknown_write.yul | 18 ++++---- .../loadResolver/merge_with_rewrite.yul | 14 +++--- .../loadResolver/mload_in_function.yul | 12 ++--- .../loadResolver/mload_self.yul | 10 +++-- .../mstore_in_function_loop_body.yul | 12 ++--- .../mstore_in_function_loop_init.yul | 12 ++--- .../loadResolver/multi_sload_loop.yul | 24 +++++----- .../loadResolver/re_store_memory.yul | 16 ++++--- .../loadResolver/re_store_storage.yul | 16 ++++--- .../loadResolver/reassign.yul | 12 ++--- .../reassign_value_expression.yul | 24 +++++----- .../loadResolver/second_mstore_with_delta.yul | 18 ++++---- .../loadResolver/second_store.yul | 14 +++--- .../loadResolver/second_store_same_value.yul | 14 +++--- .../loadResolver/second_store_with_delta.yul | 18 ++++---- .../side_effects_of_user_functions.yul | 20 +++++---- .../yulOptimizerTests/loadResolver/simple.yul | 8 ++-- .../loadResolver/simple_memory.yul | 8 ++-- .../loadResolver/staticcall.yul | 22 +++++----- .../loadResolver/verbatim_mload.yul | 12 ++--- .../loadResolver/verbatim_sload.yul | 18 ++++---- .../splitJoin/control_flow.yul | 10 +++-- .../yulOptimizerTests/splitJoin/functions.yul | 14 +++--- .../yulOptimizerTests/splitJoin/smoke.yul | 2 +- .../yulOptimizerTests/ssaAndBack/for_loop.yul | 14 +++--- .../ssaAndBack/multi_assign.yul | 6 ++- .../ssaAndBack/multi_assign_if.yul | 8 ++-- .../ssaAndBack/multi_assign_multi_var_if.yul | 18 ++++---- .../multi_assign_multi_var_switch.yul | 32 +++++++------- .../ssaAndBack/multi_assign_switch.yul | 12 ++--- .../yulOptimizerTests/ssaAndBack/simple.yul | 6 ++- .../ssaAndBack/single_assign_if.yul | 8 ++-- .../ssaAndBack/single_assign_switch.yul | 12 ++--- .../ssaAndBack/ssaReverse.yul | 6 ++- .../yulOptimizerTests/ssaAndBack/two_vars.yul | 16 ++++--- .../stackCompressor/inlineInBlock.yul | 4 +- .../stackCompressor/inlineInFunction.yul | 2 +- .../stackCompressor/noInline.yul | 2 +- .../stackCompressor/unusedPrunerWithMSize.yul | 20 +++++---- .../unusedPruner/functions.yul | 2 +- .../unusedPruner/intermediate_assignment.yul | 6 ++- .../intermediate_multi_assignment.yul | 8 ++-- .../yulOptimizerTests/unusedPruner/keccak.yul | 6 ++- .../movable_user_defined_function.yul | 2 +- .../yulOptimizerTests/unusedPruner/msize.yul | 6 ++- .../unusedPruner/multi_assign.yul | 8 ++-- .../unusedPruner/multi_assignments.yul | 8 ++-- .../unusedPruner/multi_declarations.yul | 2 +- .../unusedPruner/multi_declare.yul | 2 +- .../multi_partial_assignments.yul | 6 ++- .../unusedPruner/no_msize.yul | 2 +- .../yulOptimizerTests/unusedPruner/pop.yul | 2 +- .../yulOptimizerTests/unusedPruner/smoke.yul | 2 +- .../unusedPruner/trivial.yul | 2 +- .../unusedPruner/verbatim.yul | 8 ++-- test/yulPhaser/Program.cpp | 5 ++- 159 files changed, 893 insertions(+), 638 deletions(-) diff --git a/test/libyul/yulOptimizerTests/blockFlattener/basic.yul b/test/libyul/yulOptimizerTests/blockFlattener/basic.yul index e576174367..5b49552fb9 100644 --- a/test/libyul/yulOptimizerTests/blockFlattener/basic.yul +++ b/test/libyul/yulOptimizerTests/blockFlattener/basic.yul @@ -1,21 +1,25 @@ { - let _1 := mload(0) - let f_a := mload(1) - let f_r { - f_a := mload(f_a) - f_r := add(f_a, calldatasize()) + let _1 := mload(0) + let f_a := mload(1) + let f_r + { + f_a := mload(f_a) + f_r := add(f_a, calldatasize()) + } + let z := mload(2) } - let z := mload(2) } // ---- // step: blockFlattener // // { -// let _1 := mload(0) -// let f_a := mload(1) -// let f_r -// f_a := mload(f_a) -// f_r := add(f_a, calldatasize()) -// let z := mload(2) +// { +// let _1 := mload(0) +// let f_a := mload(1) +// let f_r +// f_a := mload(f_a) +// f_r := add(f_a, calldatasize()) +// let z := mload(2) +// } // } diff --git a/test/libyul/yulOptimizerTests/blockFlattener/for_stmt.yul b/test/libyul/yulOptimizerTests/blockFlattener/for_stmt.yul index a5be68a7ce..c587c47a3a 100644 --- a/test/libyul/yulOptimizerTests/blockFlattener/for_stmt.yul +++ b/test/libyul/yulOptimizerTests/blockFlattener/for_stmt.yul @@ -1,12 +1,16 @@ { - for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { - a := add(a, 1) + { + for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } { + a := add(a, 1) + } } } // ---- // step: blockFlattener // // { -// for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } -// { a := add(a, 1) } +// { +// for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } +// { a := add(a, 1) } +// } // } diff --git a/test/libyul/yulOptimizerTests/blockFlattener/if_stmt.yul b/test/libyul/yulOptimizerTests/blockFlattener/if_stmt.yul index f31c5f979c..00740fb133 100644 --- a/test/libyul/yulOptimizerTests/blockFlattener/if_stmt.yul +++ b/test/libyul/yulOptimizerTests/blockFlattener/if_stmt.yul @@ -1,21 +1,25 @@ { - if add(mload(7), sload(mload(3))) { - let y := add(mload(3), 3) - { - y := add(y, 7) - } + if add(mload(7), sload(mload(3))) + { + let y := add(mload(3), 3) + { + y := add(y, 7) + } + } + let t := add(3, 9) } - let t := add(3, 9) } // ---- // step: blockFlattener // // { -// if add(mload(7), sload(mload(3))) // { -// let y := add(mload(3), 3) -// y := add(y, 7) +// if add(mload(7), sload(mload(3))) +// { +// let y := add(mload(3), 3) +// y := add(y, 7) +// } +// let t := add(3, 9) // } -// let t := add(3, 9) // } diff --git a/test/libyul/yulOptimizerTests/blockFlattener/many_nested_blocks.yul b/test/libyul/yulOptimizerTests/blockFlattener/many_nested_blocks.yul index d7fd4b45a4..d1051a115b 100644 --- a/test/libyul/yulOptimizerTests/blockFlattener/many_nested_blocks.yul +++ b/test/libyul/yulOptimizerTests/blockFlattener/many_nested_blocks.yul @@ -1,29 +1,33 @@ { - let a := 3 - let b := 4 { - a := add(b, 3) - let c := 5 + let a := 3 + let b := 4 { - b := add(b, 4) + a := add(b, 3) + let c := 5 { - c := add(a, 5) - } - b := add(a, b) + b := add(b, 4) + { + c := add(a, 5) + } + b := add(a, b) + } + a := add(a, c) } - a := add(a, c) } } // ---- // step: blockFlattener // // { -// let a := 3 -// let b := 4 -// a := add(b, 3) -// let c := 5 -// b := add(b, 4) -// c := add(a, 5) -// b := add(a, b) -// a := add(a, c) +// { +// let a := 3 +// let b := 4 +// a := add(b, 3) +// let c := 5 +// b := add(b, 4) +// c := add(a, 5) +// b := add(a, b) +// a := add(a, c) +// } // } diff --git a/test/libyul/yulOptimizerTests/blockFlattener/switch_stmt.yul b/test/libyul/yulOptimizerTests/blockFlattener/switch_stmt.yul index 0b2a8245de..27b9d96dfd 100644 --- a/test/libyul/yulOptimizerTests/blockFlattener/switch_stmt.yul +++ b/test/libyul/yulOptimizerTests/blockFlattener/switch_stmt.yul @@ -1,23 +1,27 @@ { + { let a := 1 switch calldataload(0) case 0 { { { mstore(0, 1) } } a := 8 } default { a := 3 { a := 4 } } a := 5 + } } // ---- // step: blockFlattener // // { -// let a := 1 -// switch calldataload(0) -// case 0 { -// mstore(0, 1) -// a := 8 +// { +// let a := 1 +// switch calldataload(0) +// case 0 { +// mstore(0, 1) +// a := 8 +// } +// default { +// a := 3 +// a := 4 +// } +// a := 5 // } -// default { -// a := 3 -// a := 4 -// } -// a := 5 // } diff --git a/test/libyul/yulOptimizerTests/circularReferencesPruner/called_from_non_function.yul b/test/libyul/yulOptimizerTests/circularReferencesPruner/called_from_non_function.yul index 739ba78bff..909d12533c 100644 --- a/test/libyul/yulOptimizerTests/circularReferencesPruner/called_from_non_function.yul +++ b/test/libyul/yulOptimizerTests/circularReferencesPruner/called_from_non_function.yul @@ -9,8 +9,10 @@ // step: circularReferencesPruner // // { -// let a -// a := h() +// { +// let a +// a := h() +// } // function f() -> x // { x := g() } // function g() -> y diff --git a/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_different_names.yul b/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_different_names.yul index ac04f96a81..f78b9fb992 100644 --- a/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_different_names.yul +++ b/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_different_names.yul @@ -11,4 +11,4 @@ // ---- // step: circularReferencesPruner // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_same_name.yul b/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_same_name.yul index 02ac2317de..858a48d85b 100644 --- a/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_same_name.yul +++ b/test/libyul/yulOptimizerTests/circularReferencesPruner/nested_same_name.yul @@ -11,4 +11,4 @@ // ---- // step: circularReferencesPruner // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/circularReferencesPruner/trivial.yul b/test/libyul/yulOptimizerTests/circularReferencesPruner/trivial.yul index 4398bc29f4..ebb8a329c8 100644 --- a/test/libyul/yulOptimizerTests/circularReferencesPruner/trivial.yul +++ b/test/libyul/yulOptimizerTests/circularReferencesPruner/trivial.yul @@ -5,4 +5,4 @@ // ---- // step: circularReferencesPruner // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/if_condition.yul b/test/libyul/yulOptimizerTests/expressionJoiner/if_condition.yul index 045168cf13..f7e0e2ea16 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/if_condition.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/if_condition.yul @@ -14,6 +14,8 @@ // step: expressionJoiner // // { -// if add(mload(7), sload(mload(3))) { let y := add(mload(3), 3) } -// let t := add(3, 9) +// { +// if add(mload(7), sload(mload(3))) { let y := add(mload(3), 3) } +// let t := add(3, 9) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/muli_wrong_order3.yul b/test/libyul/yulOptimizerTests/expressionJoiner/muli_wrong_order3.yul index 461285ae24..b2f75828e8 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/muli_wrong_order3.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/muli_wrong_order3.yul @@ -8,7 +8,9 @@ // step: expressionJoiner // // { -// let a := mload(3) -// let b := mload(6) -// sstore(mul(add(b, a), mload(2)), 3) +// { +// let a := mload(3) +// let b := mload(6) +// sstore(mul(add(b, a), mload(2)), 3) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/multi.yul b/test/libyul/yulOptimizerTests/expressionJoiner/multi.yul index 5fcd2c5bf2..6a9e1a336e 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/multi.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/multi.yul @@ -8,5 +8,7 @@ // step: expressionJoiner // // { -// sstore(mul(add(mload(6), mload(2)), 2), 3) +// { +// sstore(mul(add(mload(6), mload(2)), 2), 3) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/multi_reference.yul b/test/libyul/yulOptimizerTests/expressionJoiner/multi_reference.yul index ed209e597d..cf90aa836f 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/multi_reference.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/multi_reference.yul @@ -7,6 +7,8 @@ // step: expressionJoiner // // { -// let a := mload(2) -// let b := add(a, a) +// { +// let a := mload(2) +// let b := add(a, a) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order.yul b/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order.yul index 2837f70330..16bd1adedd 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order.yul @@ -11,6 +11,8 @@ // step: expressionJoiner // // { -// let a := mload(2) -// sstore(mul(a, add(2, mload(6))), 3) +// { +// let a := mload(2) +// sstore(mul(a, add(2, mload(6))), 3) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order2.yul b/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order2.yul index d69f9d8a5d..25cf9676cb 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order2.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order2.yul @@ -8,6 +8,8 @@ // step: expressionJoiner // // { -// let a := mload(2) -// sstore(mul(add(a, mload(6)), 2), 3) +// { +// let a := mload(2) +// sstore(mul(add(a, mload(6)), 2), 3) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_across_blocks.yul b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_across_blocks.yul index 0e4f1916a2..f31be09c96 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_across_blocks.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_across_blocks.yul @@ -15,6 +15,8 @@ // step: expressionJoiner // // { -// let x := calldataload(mload(2)) -// sstore(x, 3) +// { +// let x := calldataload(mload(2)) +// sstore(x, 3) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition1.yul b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition1.yul index b453446ad2..7e81adc7de 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition1.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition1.yul @@ -5,6 +5,8 @@ // step: expressionJoiner // // { -// for { let b := mload(1) } b { } -// { } +// { +// for { let b := mload(1) } b { } +// { } +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition2.yul b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition2.yul index ab41999d50..bc5c5106df 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition2.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition2.yul @@ -6,7 +6,9 @@ // step: expressionJoiner // // { -// let a := mload(0) -// for { } a { } -// { } +// { +// let a := mload(0) +// for { } a { } +// { } +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/only_assignment.yul b/test/libyul/yulOptimizerTests/expressionJoiner/only_assignment.yul index 30bf466348..ac3d8e6221 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/only_assignment.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/only_assignment.yul @@ -9,6 +9,7 @@ // step: expressionJoiner // // { +// { } // function f(a) -> x // { // a := mload(2) diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/reassignment.yul b/test/libyul/yulOptimizerTests/expressionJoiner/reassignment.yul index e327d0b33f..2b5cce251f 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/reassignment.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/reassignment.yul @@ -8,7 +8,9 @@ // step: expressionJoiner // // { -// let a := mload(2) -// let b := mload(a) -// a := 4 +// { +// let a := mload(2) +// let b := mload(a) +// a := 4 +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/simple.yul b/test/libyul/yulOptimizerTests/expressionJoiner/simple.yul index 5ec8a900ad..ed8a282622 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/simple.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/simple.yul @@ -7,5 +7,7 @@ // step: expressionJoiner // // { -// sstore(calldataload(mload(2)), 3) +// { +// sstore(calldataload(mload(2)), 3) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/single_wrong_order.yul b/test/libyul/yulOptimizerTests/expressionJoiner/single_wrong_order.yul index 812cb7e7c6..beb3b8ab59 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/single_wrong_order.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/single_wrong_order.yul @@ -9,6 +9,8 @@ // step: expressionJoiner // // { -// let b := sload(mload(3)) -// sstore(add(b, mload(7)), 0) +// { +// let b := sload(mload(3)) +// sstore(add(b, mload(7)), 0) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/smoke.yul b/test/libyul/yulOptimizerTests/expressionJoiner/smoke.yul index 77f73f1126..69c4afdda6 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/smoke.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/smoke.yul @@ -2,4 +2,4 @@ // ---- // step: expressionJoiner // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/switch_expression.yul b/test/libyul/yulOptimizerTests/expressionJoiner/switch_expression.yul index 08f7bb9fb0..c17e8d3dc1 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/switch_expression.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/switch_expression.yul @@ -18,8 +18,10 @@ // step: expressionJoiner // // { -// switch add(mload(7), sload(mload(3))) -// case 3 { let y := add(mload(3), 3) } -// default { sstore(1, 0) } -// let t := add(3, 9) +// { +// switch add(mload(7), sload(mload(3))) +// case 3 { let y := add(mload(3), 3) } +// default { sstore(1, 0) } +// let t := add(3, 9) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/triple.yul b/test/libyul/yulOptimizerTests/expressionJoiner/triple.yul index d6c652e2c0..e0a5dca4d2 100644 --- a/test/libyul/yulOptimizerTests/expressionJoiner/triple.yul +++ b/test/libyul/yulOptimizerTests/expressionJoiner/triple.yul @@ -9,5 +9,7 @@ // step: expressionJoiner // // { -// sstore(mul(add(mload(7), mload(6)), mload(2)), 3) +// { +// sstore(mul(add(mload(7), mload(6)), mload(2)), 3) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/assigned_vars_multi.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/assigned_vars_multi.yul index b73742ced1..1fce6767ed 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/assigned_vars_multi.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/assigned_vars_multi.yul @@ -8,8 +8,10 @@ // step: expressionSimplifier // // { -// let c, d := f() -// sstore(add(add(d, c), 7), 20) +// { +// let c, d := f() +// sstore(add(add(d, c), 7), 20) +// } // function f() -> x, z // { } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/byte_after_shr_non_mul_of_8.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/byte_after_shr_non_mul_of_8.yul index e7c7bbf881..f9405e1013 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/byte_after_shr_non_mul_of_8.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/byte_after_shr_non_mul_of_8.yul @@ -6,4 +6,4 @@ // ---- // step: expressionSimplifier // -// { sstore(0, 0) } +// { { sstore(0, 0) } } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and.yul index 7288ef56f9..9bb106c89e 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and.yul @@ -13,7 +13,9 @@ // step: expressionSimplifier // // { -// let x := calldataload(0) -// let a := and(0xff, and(shr(248, x), 255)) -// sstore(a, shr(12, and(shl(8, x), 15790080))) +// { +// let x := calldataload(0) +// let a := and(0xff, and(shr(248, x), 255)) +// sstore(a, shr(12, and(shl(8, x), 15790080))) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and_2.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and_2.yul index f57a5108b8..6e39f2a1dc 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and_2.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and_2.yul @@ -24,25 +24,27 @@ // step: expressionSimplifier // // { -// let x := calldataload(0) -// let _2 := 0xf -// let _5 := and(shr(248, x), 0) -// let _10 := 0xff -// let a := and(_5, 255) -// let _14 := and(shr(4, x), 3855) -// let _15 := 12 -// let b := shl(_15, _14) -// let _19 := and(shr(4, x), 3855) -// let c := shl(_15, _19) -// let d := shl(_15, and(shr(255, x), 0)) -// let e := shl(_10, _19) -// let f := 0 -// let g := 0 -// sstore(10, a) -// sstore(11, b) -// sstore(_15, c) -// sstore(13, d) -// sstore(14, e) -// sstore(_2, f) -// sstore(16, g) +// { +// let x := calldataload(0) +// let _2 := 0xf +// let _5 := and(shr(248, x), 0) +// let _10 := 0xff +// let a := and(_5, 255) +// let _14 := and(shr(4, x), 3855) +// let _15 := 12 +// let b := shl(_15, _14) +// let _19 := and(shr(4, x), 3855) +// let c := shl(_15, _19) +// let d := shl(_15, and(shr(255, x), 0)) +// let e := shl(_10, _19) +// let f := 0 +// let g := 0 +// sstore(10, a) +// sstore(11, b) +// sstore(_15, c) +// sstore(13, d) +// sstore(14, e) +// sstore(_2, f) +// sstore(16, g) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and_3.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and_3.yul index 14ff1b375d..9df15b4e9c 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and_3.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/combine_shift_and_and_3.yul @@ -21,17 +21,19 @@ // step: expressionSimplifier // // { -// let x := calldataload(0) -// let a := and(shl(8, x), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000) -// let b := and(shr(8, x), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0) -// let c := and(shr(8, x), 0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) -// let d := and(shl(8, x), 0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) -// let _14 := 150 -// let e := shl(_14, and(shl(148, x), 0x3ffffffffffffffffffffffffff0000000000000000000000000000000000000)) -// sstore(15, x) -// sstore(16, a) -// sstore(17, b) -// sstore(18, c) -// sstore(19, d) -// sstore(20, e) +// { +// let x := calldataload(0) +// let a := and(shl(8, x), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000) +// let b := and(shr(8, x), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0) +// let c := and(shr(8, x), 0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) +// let d := and(shl(8, x), 0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) +// let _14 := 150 +// let e := shl(_14, and(shl(148, x), 0x3ffffffffffffffffffffffffff0000000000000000000000000000000000000)) +// sstore(15, x) +// sstore(16, a) +// sstore(17, b) +// sstore(18, c) +// sstore(19, d) +// sstore(20, e) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/constant_propagation.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/constant_propagation.yul index 56d18fb7b3..557142fa54 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/constant_propagation.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/constant_propagation.yul @@ -5,4 +5,4 @@ // ---- // step: expressionSimplifier // -// { mstore(20, mload(0)) } +// { { mstore(20, mload(0)) } } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/constants.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/constants.yul index ce29499931..bbd8f2d122 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/constants.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/constants.yul @@ -5,4 +5,4 @@ // ---- // step: expressionSimplifier // -// { sstore(7, 13) } +// { { sstore(7, 13) } } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/create2_and_mask.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/create2_and_mask.yul index 8a52659922..a431c57a6c 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/create2_and_mask.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/create2_and_mask.yul @@ -12,9 +12,11 @@ // step: expressionSimplifier // // { -// let _1 := 0xffffffffffffffffffffffffffffffffffffffff -// let _2 := 0 -// let _3 := 0x20 -// let a := and(create2(_2, _2, _3, _2), _1) -// sstore(a, and(_1, create2(_2, _2, _3, _2))) +// { +// let _1 := 0xffffffffffffffffffffffffffffffffffffffff +// let _2 := 0 +// let _3 := 0x20 +// let a := and(create2(_2, _2, _3, _2), _1) +// sstore(a, and(_1, create2(_2, _2, _3, _2))) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/create_and_mask.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/create_and_mask.yul index 8e77b8726b..3710cbebdf 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/create_and_mask.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/create_and_mask.yul @@ -11,10 +11,12 @@ // step: expressionSimplifier // // { -// let _1 := 0x20 -// let _2 := 0 -// let c := create(_2, _2, _1) -// let _4 := 0xffffffffffffffffffffffffffffffffffffffff -// let a := and(c, _4) -// sstore(a, and(_4, create(_2, _2, _1))) +// { +// let _1 := 0x20 +// let _2 := 0 +// let c := create(_2, _2, _1) +// let _4 := 0xffffffffffffffffffffffffffffffffffffffff +// let a := and(c, _4) +// sstore(a, and(_4, create(_2, _2, _1))) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/exp_simplifications.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/exp_simplifications.yul index bfc1cbb2b0..4a5d218053 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/exp_simplifications.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/exp_simplifications.yul @@ -13,12 +13,14 @@ // step: expressionSimplifier // // { -// let _1 := 0 -// let t := calldataload(_1) -// sstore(_1, iszero(t)) -// sstore(1, 1) -// let _8 := 2 -// sstore(_8, shl(t, 1)) -// sstore(3, exp(8, t)) -// sstore(4, sub(iszero(and(t, 1)), and(t, 1))) +// { +// let _1 := 0 +// let t := calldataload(_1) +// sstore(_1, iszero(t)) +// sstore(1, 1) +// let _8 := 2 +// sstore(_8, shl(t, 1)) +// sstore(3, exp(8, t)) +// sstore(4, sub(iszero(and(t, 1)), and(t, 1))) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/idempotency.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/idempotency.yul index 9698dfdff4..5b11fa7c8e 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/idempotency.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/idempotency.yul @@ -9,8 +9,10 @@ // step: expressionSimplifier // // { -// let x := calldataload(0) -// let z := calldataload(1) -// let t := and(x, z) -// sstore(t, or(x, z)) +// { +// let x := calldataload(0) +// let z := calldataload(1) +// let t := and(x, z) +// sstore(t, or(x, z)) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_complex.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_complex.yul index 6bb6a751b8..af88cbac6d 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_complex.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_complex.yul @@ -5,4 +5,4 @@ // ---- // step: expressionSimplifier // -// { sstore(0, 0) } +// { { sstore(0, 0) } } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_negative.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_negative.yul index 686ae2b635..80f19a1b53 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_negative.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_negative.yul @@ -6,6 +6,8 @@ // step: expressionSimplifier // // { -// let _1 := 0 -// sstore(_1, sub(calldataload(1), calldataload(_1))) +// { +// let _1 := 0 +// sstore(_1, sub(calldataload(1), calldataload(_1))) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_simple.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_simple.yul index 57d84ae153..87677dfea2 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_simple.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_simple.yul @@ -6,4 +6,4 @@ // ---- // step: expressionSimplifier // -// { sstore(0, 0) } +// { { sstore(0, 0) } } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/including_function_calls.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/including_function_calls.yul index 8ebb9e51dd..42cd772e9f 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/including_function_calls.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/including_function_calls.yul @@ -7,7 +7,7 @@ // step: expressionSimplifier // // { -// sstore(0, f()) +// { sstore(0, f()) } // function f() -> a // { } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/inside_for.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/inside_for.yul index b8b3ee35d8..5a7c8939a6 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/inside_for.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/inside_for.yul @@ -6,7 +6,9 @@ // step: expressionSimplifier // // { -// let a := 10 -// for { } iszero(iszero(a)) { a := add(a, 1) } -// { } +// { +// let a := 10 +// for { } iszero(iszero(a)) { a := add(a, 1) } +// { } +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/invariant.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/invariant.yul index d7da5e41fe..78565bbe5b 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/invariant.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/invariant.yul @@ -6,4 +6,4 @@ // ---- // step: expressionSimplifier // -// { sstore(0, mload(0)) } +// { { sstore(0, mload(0)) } } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/iszero_sub_to_eq.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/iszero_sub_to_eq.yul index 7efa54b021..3e0f785e95 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/iszero_sub_to_eq.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/iszero_sub_to_eq.yul @@ -10,7 +10,9 @@ // step: expressionSimplifier // // { -// let _1 := 0 -// let a := calldataload(_1) -// if eq(a, calldataload(0x20)) { sstore(_1, 1) } +// { +// let _1 := 0 +// let a := calldataload(_1) +// if eq(a, calldataload(0x20)) { sstore(_1, 1) } +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/large_byte_access.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/large_byte_access.yul index 22bfaf91fd..19d65dca41 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/large_byte_access.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/large_byte_access.yul @@ -13,14 +13,16 @@ // step: expressionSimplifier // // { -// let _1 := 0 -// let a := calldataload(_1) -// let b := 0 -// let c := byte(20, a) -// pop(create(_1, _1, 0x20)) -// let d := 0 -// sstore(7, a) -// sstore(8, b) -// sstore(9, c) -// sstore(10, d) +// { +// let _1 := 0 +// let a := calldataload(_1) +// let b := 0 +// let c := byte(20, a) +// pop(create(_1, _1, 0x20)) +// let d := 0 +// sstore(7, a) +// sstore(8, b) +// sstore(9, c) +// sstore(10, d) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_1.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_1.yul index 696d0b1117..88ed926b18 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_1.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_1.yul @@ -5,6 +5,8 @@ // step: expressionSimplifier // // { -// let _4 := 0 -// mstore(_4, and(calldataload(_4), 255)) +// { +// let _4 := 0 +// mstore(_4, and(calldataload(_4), 255)) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_2.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_2.yul index 81fe7e117e..a62c5904cf 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_2.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_2.yul @@ -5,6 +5,8 @@ // step: expressionSimplifier // // { -// let _4 := 0 -// mstore(_4, and(calldataload(_4), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) +// { +// let _4 := 0 +// mstore(_4, and(calldataload(_4), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_arguments.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_arguments.yul index eca9021ea6..c426935219 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_arguments.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_arguments.yul @@ -7,9 +7,11 @@ // step: expressionSimplifier // // { -// let _2 := f(1) -// let _3 := 0 -// sstore(_3, sub(f(_3), _2)) +// { +// let _2 := f(1) +// let _3 := 0 +// sstore(_3, sub(f(_3), _2)) +// } // function f(a) -> b // { } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_names.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_names.yul index ed439b62fd..5245677053 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_names.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_names.yul @@ -8,7 +8,7 @@ // step: expressionSimplifier // // { -// sstore(0, sub(f1(), f2())) +// { sstore(0, sub(f1(), f2())) } // function f1() -> a // { } // function f2() -> b diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_equality_not_movable.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_equality_not_movable.yul index bba7cf26e5..b0215685de 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_equality_not_movable.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_equality_not_movable.yul @@ -8,7 +8,7 @@ // step: expressionSimplifier // // { -// sstore(sub(f(), f()), 8) +// { sstore(sub(f(), f()), 8) } // function f() -> a // { mstore(0, 1) } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_removes_non_constant_and_not_movable.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_removes_non_constant_and_not_movable.yul index 37065cd4dc..a7be174e35 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_removes_non_constant_and_not_movable.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_removes_non_constant_and_not_movable.yul @@ -9,9 +9,11 @@ // step: expressionSimplifier // // { -// let _1 := msize() -// let _2 := 0 -// sstore(_2, _1) -// pop(keccak256(_2, _2)) -// sstore(20, 0) +// { +// let _1 := msize() +// let _2 := 0 +// sstore(_2, _1) +// pop(keccak256(_2, _2)) +// sstore(20, 0) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_call.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_call.yul index af34e76bde..abd1b1743d 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_call.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_call.yul @@ -7,7 +7,9 @@ // step: expressionSimplifier // // { -// let _1 := 0 -// pop(call(_1, _1, _1, _1, _1, _1, _1)) -// sstore(_1, 0) +// { +// let _1 := 0 +// pop(call(_1, _1, _1, _1, _1, _1, _1)) +// sstore(_1, 0) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_func.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_func.yul index e1ec04ad1e..6465aa7974 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_func.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_func.yul @@ -8,8 +8,10 @@ // step: expressionSimplifier // // { -// pop(f()) -// mstore(0, 0) +// { +// pop(f()) +// mstore(0, 0) +// } // function f() -> x // { mstore(0, 1337) } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_func_trivial.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_func_trivial.yul index 448e071d8f..b822b402b3 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_func_trivial.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/pop_byte_shr_func_trivial.yul @@ -7,4 +7,4 @@ // ---- // step: expressionSimplifier // -// { sstore(0, 0) } +// { { sstore(0, 0) } } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/reassign.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/reassign.yul index d87b84f595..d0cf0a6eed 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/reassign.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/reassign.yul @@ -7,8 +7,10 @@ // step: expressionSimplifier // // { -// let _1 := 0 -// let x := mload(_1) -// x := _1 -// mstore(_1, 7) +// { +// let _1 := 0 +// let x := mload(_1) +// x := _1 +// mstore(_1, 7) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/remove_redundant_shift_masking.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/remove_redundant_shift_masking.yul index 060a4e13ff..a4d3012c33 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/remove_redundant_shift_masking.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/remove_redundant_shift_masking.yul @@ -12,12 +12,14 @@ // step: expressionSimplifier // // { -// let _2 := calldataload(0) -// let _5 := 0xff -// let a := shr(248, _2) -// let b := shr(248, _2) -// let c := and(shr(249, _2), 0xfa) -// let d := and(shr(247, _2), _5) -// sstore(a, b) -// sstore(c, d) +// { +// let _2 := calldataload(0) +// let _5 := 0xff +// let a := shr(248, _2) +// let b := shr(248, _2) +// let c := and(shr(249, _2), 0xfa) +// let d := and(shr(247, _2), _5) +// sstore(a, b) +// sstore(c, d) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/replace_too_large_shift.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/replace_too_large_shift.yul index 88263e98e7..85c86f0e4b 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/replace_too_large_shift.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/replace_too_large_shift.yul @@ -12,12 +12,14 @@ // step: expressionSimplifier // // { -// let a := 0 -// let b := 0 -// let _8 := calldataload(2) -// let _9 := 255 -// let c := shl(_9, _8) -// let d := shr(_9, calldataload(3)) -// sstore(a, b) -// sstore(c, d) +// { +// let a := 0 +// let b := 0 +// let _8 := calldataload(2) +// let _9 := 255 +// let c := shl(_9, _8) +// let d := shr(_9, calldataload(3)) +// sstore(a, b) +// sstore(c, d) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/return_vars_zero.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/return_vars_zero.yul index ca31e7613b..73a79410df 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/return_vars_zero.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/return_vars_zero.yul @@ -10,7 +10,7 @@ // step: expressionSimplifier // // { -// let t, v := f() +// { let t, v := f() } // function f() -> c, d // { sstore(0, 7) } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/reversed.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/reversed.yul index 32c8775721..b83b77c216 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/reversed.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/reversed.yul @@ -6,6 +6,8 @@ // step: expressionSimplifier // // { -// let _1 := 0 -// sstore(_1, mload(_1)) +// { +// let _1 := 0 +// sstore(_1, mload(_1)) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_not_supported.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_not_supported.yul index 8a9bb7c199..3f30eefd65 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_not_supported.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_not_supported.yul @@ -6,4 +6,6 @@ // ---- // step: expressionSimplifier // -// { sstore(0, balance(address())) } +// { +// { sstore(0, balance(address())) } +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_split.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_split.yul index b14098ffef..72562a2fde 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_split.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_split.yul @@ -9,6 +9,8 @@ // step: expressionSimplifier // // { -// let a := address() -// sstore(a, selfbalance()) +// { +// let a := address() +// sstore(a, selfbalance()) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_supported.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_supported.yul index bc3c6c4d70..7ed42b360e 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_supported.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/selfbalance_supported.yul @@ -6,4 +6,4 @@ // ---- // step: expressionSimplifier // -// { sstore(0, selfbalance()) } +// { { sstore(0, selfbalance()) } } 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 14d65c4e92..bd567a69a6 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/side_effects_in_for_condition.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/side_effects_in_for_condition.yul @@ -9,6 +9,8 @@ // step: expressionSimplifier // // { -// for { } div(create(0, 1, 0), shl(msize(), 1)) { } -// { } +// { +// for { } div(create(0, 1, 0), shl(msize(), 1)) { } +// { } +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/smoke.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/smoke.yul index 30a2f5e901..0fae4792fd 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/smoke.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/smoke.yul @@ -2,4 +2,4 @@ // ---- // step: expressionSimplifier // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/unassigend_vars_multi.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/unassigend_vars_multi.yul index b052fe4033..a15cca231d 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/unassigend_vars_multi.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/unassigend_vars_multi.yul @@ -8,6 +8,8 @@ // step: expressionSimplifier // // { -// let c, d -// sstore(d, 7) +// { +// let c, d +// sstore(d, 7) +// } // } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/unassigned_vars.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/unassigned_vars.yul index 9dd4e3365d..b6828cf8c4 100644 --- a/test/libyul/yulOptimizerTests/expressionSimplifier/unassigned_vars.yul +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/unassigned_vars.yul @@ -8,4 +8,4 @@ // ---- // step: expressionSimplifier // -// { sstore(8, 7) } +// { { sstore(8, 7) } } diff --git a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul index c1ce89bcfe..fbc0ca8561 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul @@ -13,6 +13,7 @@ // step: fullInliner // // { +// { } // function f(a) -> b // { b := sload(mload(a)) } // function g() -> x_1 diff --git a/test/libyul/yulOptimizerTests/fullSimplify/constant_propagation.yul b/test/libyul/yulOptimizerTests/fullSimplify/constant_propagation.yul index 968ec47673..a13ad93953 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/constant_propagation.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/constant_propagation.yul @@ -6,6 +6,8 @@ // step: fullSimplify // // { -// let _2 := 0 -// mstore(mload(_2), _2) +// { +// let _2 := 0 +// mstore(mload(_2), _2) +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/constants.yul b/test/libyul/yulOptimizerTests/fullSimplify/constants.yul index 0b31d361f9..2d2fb70444 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/constants.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/constants.yul @@ -5,4 +5,4 @@ // ---- // step: fullSimplify // -// { mstore(0, 13) } +// { { mstore(0, 13) } } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_complex.yul b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_complex.yul index 452ceaae6f..eb104f6337 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_complex.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_complex.yul @@ -5,4 +5,4 @@ // ---- // step: fullSimplify // -// { mstore(0, 0) } +// { { mstore(0, 0) } } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_negative.yul b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_negative.yul index 8c5e4e5dfc..daf34eed5e 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_negative.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_negative.yul @@ -6,6 +6,8 @@ // step: fullSimplify // // { -// let _1 := 0 -// mstore(_1, sub(calldataload(1), calldataload(_1))) +// { +// let _1 := 0 +// mstore(_1, sub(calldataload(1), calldataload(_1))) +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_simple.yul b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_simple.yul index e8efb735c0..6f90c583ef 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_simple.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_simple.yul @@ -5,4 +5,4 @@ // ---- // step: fullSimplify // -// { mstore(0, 0) } +// { { mstore(0, 0) } } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/including_function_calls.yul b/test/libyul/yulOptimizerTests/fullSimplify/including_function_calls.yul index 090b3cde65..08dd01646d 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/including_function_calls.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/including_function_calls.yul @@ -7,7 +7,7 @@ // step: fullSimplify // // { -// mstore(f(), 0) +// { mstore(f(), 0) } // function f() -> a // { } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/inside_for.yul b/test/libyul/yulOptimizerTests/fullSimplify/inside_for.yul index 9d4e52dc1b..911c668172 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/inside_for.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/inside_for.yul @@ -7,7 +7,9 @@ // step: fullSimplify // // { -// let a := 10 -// for { } iszero(iszero(a)) { a := add(a, 1) } -// { } +// { +// let a := 10 +// for { } iszero(iszero(a)) { a := add(a, 1) } +// { } +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/invariant.yul b/test/libyul/yulOptimizerTests/fullSimplify/invariant.yul index 6874918186..0ab5cc6ed8 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/invariant.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/invariant.yul @@ -11,8 +11,10 @@ // step: fullSimplify // // { -// let a := calldataload(0) -// let _4 := 0 -// let b := a -// mstore(b, eq(calldataload(_4), a)) +// { +// let a := calldataload(0) +// let _4 := 0 +// let b := a +// mstore(b, eq(calldataload(_4), a)) +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/mod_and_1.yul b/test/libyul/yulOptimizerTests/fullSimplify/mod_and_1.yul index 1e448c9a4f..c10345e4ee 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/mod_and_1.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/mod_and_1.yul @@ -5,6 +5,8 @@ // step: fullSimplify // // { -// let _4 := 0 -// mstore(_4, and(calldataload(_4), 255)) +// { +// let _4 := 0 +// mstore(_4, and(calldataload(_4), 255)) +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/mod_and_2.yul b/test/libyul/yulOptimizerTests/fullSimplify/mod_and_2.yul index 0756c1841d..fc171337f9 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/mod_and_2.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/mod_and_2.yul @@ -5,6 +5,8 @@ // step: fullSimplify // // { -// let _4 := 0 -// mstore(_4, and(calldataload(_4), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) +// { +// let _4 := 0 +// mstore(_4, and(calldataload(_4), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_arguments.yul b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_arguments.yul index 517bbe442b..e42b6c0986 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_arguments.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_arguments.yul @@ -6,9 +6,11 @@ // step: fullSimplify // // { -// let _2 := f(1) -// let _3 := 0 -// mstore(_3, sub(f(_3), _2)) +// { +// let _2 := f(1) +// let _3 := 0 +// mstore(_3, sub(f(_3), _2)) +// } // function f(a) -> b // { } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_names.yul b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_names.yul index 7f8fddf2e5..31490cbc06 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_names.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_names.yul @@ -8,7 +8,7 @@ // step: fullSimplify // // { -// mstore(0, sub(f1(), f2())) +// { mstore(0, sub(f1(), f2())) } // function f1() -> a // { } // function f2() -> b diff --git a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_equality_not_movable.yul b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_equality_not_movable.yul index 52030fe88f..8162119e8f 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_equality_not_movable.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_equality_not_movable.yul @@ -8,7 +8,7 @@ // step: fullSimplify // // { -// mstore(0, sub(f(), f())) +// { mstore(0, sub(f(), f())) } // function f() -> a // { mstore(1, 2) } // } 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 05fc9447d6..0e366e6d40 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 @@ -7,7 +7,9 @@ // step: fullSimplify // // { -// let _1 := 0 -// pop(create(_1, _1, _1)) -// mstore(_1, 0) +// { +// let _1 := 0 +// pop(create(_1, _1, _1)) +// mstore(_1, 0) +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/operations.yul b/test/libyul/yulOptimizerTests/fullSimplify/operations.yul index 93b4242330..a0fb676014 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/operations.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/operations.yul @@ -23,22 +23,24 @@ // step: fullSimplify // // { -// mstore(1, 0) -// mstore(2, 0) -// mstore(3, 0) -// mstore(4, 0) -// mstore(5, 0) -// mstore(6, 0) -// mstore(7, 0) -// mstore(8, 0) -// mstore(9, 0) -// mstore(10, 0) -// mstore(11, 0) -// mstore(12, 0) -// mstore(13, 0) -// mstore(14, 0) -// mstore(15, 0) -// mstore(16, 0) -// mstore(17, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) -// mstore(18, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) +// { +// mstore(1, 0) +// mstore(2, 0) +// mstore(3, 0) +// mstore(4, 0) +// mstore(5, 0) +// mstore(6, 0) +// mstore(7, 0) +// mstore(8, 0) +// mstore(9, 0) +// mstore(10, 0) +// mstore(11, 0) +// mstore(12, 0) +// mstore(13, 0) +// mstore(14, 0) +// mstore(15, 0) +// mstore(16, 0) +// mstore(17, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) +// mstore(18, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/reversed.yul b/test/libyul/yulOptimizerTests/fullSimplify/reversed.yul index 5fe6324959..b3b98d061a 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/reversed.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/reversed.yul @@ -6,6 +6,8 @@ // step: fullSimplify // // { -// let _1 := 0 -// mstore(_1, mload(_1)) +// { +// let _1 := 0 +// mstore(_1, mload(_1)) +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/signextend.yul b/test/libyul/yulOptimizerTests/fullSimplify/signextend.yul index 9ebdf01289..2dd64525f9 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/signextend.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/signextend.yul @@ -8,6 +8,8 @@ // step: fullSimplify // // { -// mstore(0, 7) -// mstore(1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) +// { +// mstore(0, 7) +// mstore(1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) +// } // } diff --git a/test/libyul/yulOptimizerTests/fullSimplify/smoke.yul b/test/libyul/yulOptimizerTests/fullSimplify/smoke.yul index 15ff14a845..a5b71eea8d 100644 --- a/test/libyul/yulOptimizerTests/fullSimplify/smoke.yul +++ b/test/libyul/yulOptimizerTests/fullSimplify/smoke.yul @@ -2,4 +2,4 @@ // ---- // step: fullSimplify // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/loadResolver/double_mload.yul b/test/libyul/yulOptimizerTests/loadResolver/double_mload.yul index b75f9c07b9..1448354763 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/double_mload.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/double_mload.yul @@ -8,6 +8,8 @@ // step: loadResolver // // { -// let a := mload(calldataload(0)) -// sstore(a, a) +// { +// let a := mload(calldataload(0)) +// sstore(a, a) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/double_mload_with_other_reassignment.yul b/test/libyul/yulOptimizerTests/loadResolver/double_mload_with_other_reassignment.yul index 19d2174231..7ffac34c0b 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/double_mload_with_other_reassignment.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/double_mload_with_other_reassignment.yul @@ -9,8 +9,10 @@ // step: loadResolver // // { -// let x := calldataload(0) -// let a := mload(x) -// x := 7 -// sstore(a, mload(x)) +// { +// let x := calldataload(0) +// let a := mload(x) +// x := 7 +// sstore(a, mload(x)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/double_mload_with_reassignment.yul b/test/libyul/yulOptimizerTests/loadResolver/double_mload_with_reassignment.yul index b5c2f11265..7f8514875d 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/double_mload_with_reassignment.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/double_mload_with_reassignment.yul @@ -9,8 +9,10 @@ // step: loadResolver // // { -// let x := calldataload(0) -// let a := mload(x) -// a := 7 -// sstore(a, mload(x)) +// { +// let x := calldataload(0) +// let a := mload(x) +// a := 7 +// sstore(a, mload(x)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak.yul index 97b468e5fb..25b36f5fea 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/keccak.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak.yul @@ -9,8 +9,10 @@ // step: loadResolver // // { -// let _1 := 10 -// let _2 := 0 -// mstore(_2, _1) -// sstore(_2, 89717814153306320011181716697424560163256864414616650038987186496166826726056) +// { +// let _1 := 10 +// let _2 := 0 +// mstore(_2, _1) +// sstore(_2, 89717814153306320011181716697424560163256864414616650038987186496166826726056) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_crash.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_crash.yul index dd6a164eb4..18c818d15e 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/keccak_crash.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_crash.yul @@ -6,8 +6,10 @@ // step: loadResolver // // { -// for { } -// addmod(keccak256(0x0, create(0x0, 0x0, 0x0)), 0x0, 0x0) -// { } -// { } +// { +// for { } +// addmod(keccak256(0x0, create(0x0, 0x0, 0x0)), 0x0, 0x0) +// { } +// { } +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_fail1.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_fail1.yul index e1157f21d4..e4fe6484ff 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/keccak_fail1.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_fail1.yul @@ -10,9 +10,11 @@ // step: loadResolver // // { -// let _1 := 30 -// let _2 := 0 -// mstore(_2, _1) -// if calldataload(_2) { mstore(_2, 20) } -// sstore(_2, keccak256(_2, 32)) +// { +// let _1 := 30 +// let _2 := 0 +// mstore(_2, _1) +// if calldataload(_2) { mstore(_2, 20) } +// sstore(_2, keccak256(_2, 32)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_fail2.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_fail2.yul index 61a2eefb25..5a7d571a47 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/keccak_fail2.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_fail2.yul @@ -9,8 +9,10 @@ // step: loadResolver // // { -// let _1 := 10 -// mstore(100, _1) -// mstore(132, 5) -// sstore(0, keccak256(_1, 33)) +// { +// let _1 := 10 +// mstore(100, _1) +// mstore(132, 5) +// sstore(0, keccak256(_1, 33)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_short.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_short.yul index d1761b7cea..58cb7c264c 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/keccak_short.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_short.yul @@ -19,13 +19,15 @@ // step: loadResolver // // { -// let _1 := 10 -// let _2 := 0 -// mstore(_2, _1) -// sstore(_2, 9948786400348073077032572701554570401043517428989726124163377057770909578447) -// sstore(1, 110945455955148346822663466543669633859020391897956790847617069135813044810108) -// let _13 := 85131057757245807317576516368191972321038229705283732634690444270750521936266 -// let _14 := 2 -// sstore(_14, _13) -// sstore(_14, 89477152217924674838424037953991966239322087453347756267410168184682657981552) +// { +// let _1 := 10 +// let _2 := 0 +// mstore(_2, _1) +// sstore(_2, 9948786400348073077032572701554570401043517428989726124163377057770909578447) +// sstore(1, 110945455955148346822663466543669633859020391897956790847617069135813044810108) +// let _13 := 85131057757245807317576516368191972321038229705283732634690444270750521936266 +// let _14 := 2 +// sstore(_14, _13) +// sstore(_14, 89477152217924674838424037953991966239322087453347756267410168184682657981552) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_string_literal.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_string_literal.yul index 279a23959f..261f38cd1f 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/keccak_string_literal.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_string_literal.yul @@ -12,11 +12,13 @@ // step: loadResolver // // { -// let _1 := 50 -// let _2 := "abcdefghijklmn" -// mstore(_1, _2) -// let _3 := 51246744213555520563123611275127692828770413530219146609532820042079541949502 -// let _4 := 0 -// sstore(_4, _3) -// sstore(_4, add(_2, 1)) +// { +// let _1 := 50 +// let _2 := "abcdefghijklmn" +// mstore(_1, _2) +// let _3 := 51246744213555520563123611275127692828770413530219146609532820042079541949502 +// let _4 := 0 +// sstore(_4, _3) +// sstore(_4, add(_2, 1)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_symbolic_memory.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_symbolic_memory.yul index c18af0c8df..46466a062f 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/keccak_symbolic_memory.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_symbolic_memory.yul @@ -15,8 +15,10 @@ // step: loadResolver // // { -// let _1 := 0 -// mstore(calldataload(_1), 500) -// sstore(_1, 92647596584187651892918913434663110448935397770592030057655219009846081465370) -// sstore(1, 110620294328144418057589324861608220015688365608948720310623173341503153578932) +// { +// let _1 := 0 +// mstore(calldataload(_1), 500) +// sstore(_1, 92647596584187651892918913434663110448935397770592030057655219009846081465370) +// sstore(1, 110620294328144418057589324861608220015688365608948720310623173341503153578932) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/keccak_with_msize.yul b/test/libyul/yulOptimizerTests/loadResolver/keccak_with_msize.yul index fdc1e88368..5e1c7d4190 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/keccak_with_msize.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/keccak_with_msize.yul @@ -11,9 +11,11 @@ // step: loadResolver // // { -// let _1 := msize() -// let _2 := 0 -// sstore(_2, _1) -// mstore(_2, 10) -// sstore(1, keccak256(_2, 32)) +// { +// let _1 := msize() +// let _2 := 0 +// sstore(_2, _1) +// mstore(_2, 10) +// sstore(1, keccak256(_2, 32)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/loop.yul b/test/libyul/yulOptimizerTests/loadResolver/loop.yul index 3606891ee1..4587671606 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/loop.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/loop.yul @@ -8,11 +8,13 @@ // step: loadResolver // // { -// let _1 := 123213 -// let _2 := 0 -// sstore(_2, _1) -// let x := _2 -// let y -// for { } lt(x, _1) { x := add(x, 1) } -// { y := add(x, y) } +// { +// let _1 := 123213 +// let _2 := 0 +// sstore(_2, _1) +// let x := _2 +// let y +// for { } lt(x, _1) { x := add(x, 1) } +// { y := add(x, y) } +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/memory_with_different_kinds_of_invalidation.yul b/test/libyul/yulOptimizerTests/loadResolver/memory_with_different_kinds_of_invalidation.yul index 77fc5aef01..840f19005b 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/memory_with_different_kinds_of_invalidation.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/memory_with_different_kinds_of_invalidation.yul @@ -18,18 +18,20 @@ // step: loadResolver // // { -// let _1 := 9 -// let _2 := 2 -// mstore(_2, _1) -// let _4 := _1 -// let _5 := 0 -// 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) +// { +// let _1 := 9 +// let _2 := 2 +// mstore(_2, _1) +// let _4 := _1 +// let _5 := 0 +// 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_msize.yul b/test/libyul/yulOptimizerTests/loadResolver/memory_with_msize.yul index 199fb1f6c4..f54053bb10 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/memory_with_msize.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/memory_with_msize.yul @@ -9,9 +9,11 @@ // step: loadResolver // // { -// let _1 := msize() -// let _3 := calldataload(0) -// mstore(_3, _1) -// let t := mload(calldataload(10)) -// sstore(t, mload(_3)) +// { +// let _1 := msize() +// let _3 := calldataload(0) +// mstore(_3, _1) +// let t := mload(calldataload(10)) +// sstore(t, mload(_3)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/merge_known_write.yul b/test/libyul/yulOptimizerTests/loadResolver/merge_known_write.yul index e9ced5f4c3..acb96c07b1 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/merge_known_write.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/merge_known_write.yul @@ -11,12 +11,14 @@ // step: loadResolver // // { -// let _2 := calldataload(10) -// let _3 := 0 -// let _4 := calldataload(_3) -// mstore(_4, _2) -// let _5 := 1 -// if calldataload(_5) { mstore(_4, _5) } -// let t := mload(_3) -// sstore(t, mload(_4)) +// { +// let _2 := calldataload(10) +// let _3 := 0 +// let _4 := calldataload(_3) +// mstore(_4, _2) +// let _5 := 1 +// if calldataload(_5) { mstore(_4, _5) } +// let t := mload(_3) +// sstore(t, mload(_4)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/merge_known_write_with_distance.yul b/test/libyul/yulOptimizerTests/loadResolver/merge_known_write_with_distance.yul index 8ce9fba00c..1659949a3c 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/merge_known_write_with_distance.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/merge_known_write_with_distance.yul @@ -11,10 +11,12 @@ // step: loadResolver // // { -// let _2 := calldataload(10) -// let _4 := calldataload(0) -// mstore(_4, _2) -// let _5 := 1 -// if calldataload(_5) { mstore(add(_4, 0x20), _5) } -// sstore(mload(add(_4, 0x20)), _2) +// { +// let _2 := calldataload(10) +// let _4 := calldataload(0) +// mstore(_4, _2) +// let _5 := 1 +// if calldataload(_5) { mstore(add(_4, 0x20), _5) } +// sstore(mload(add(_4, 0x20)), _2) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/merge_mload_with_known_distance.yul b/test/libyul/yulOptimizerTests/loadResolver/merge_mload_with_known_distance.yul index cde3ec0e6b..18740c0490 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/merge_mload_with_known_distance.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/merge_mload_with_known_distance.yul @@ -11,9 +11,11 @@ // step: loadResolver // // { -// let _2 := calldataload(0) -// let x := mload(_2) -// let _3 := 1 -// if calldataload(_3) { mstore(add(_2, 0x20), _3) } -// sstore(mload(add(_2, 0x20)), x) +// { +// let _2 := calldataload(0) +// let x := mload(_2) +// let _3 := 1 +// if calldataload(_3) { mstore(add(_2, 0x20), _3) } +// sstore(mload(add(_2, 0x20)), x) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/merge_mload_with_rewrite.yul b/test/libyul/yulOptimizerTests/loadResolver/merge_mload_with_rewrite.yul index 5c09b9b430..00bb85c4c8 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/merge_mload_with_rewrite.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/merge_mload_with_rewrite.yul @@ -11,12 +11,14 @@ // step: loadResolver // // { -// let _1 := 2 -// let b := mload(_1) -// if calldataload(1) // { -// mstore(_1, 7) -// mstore(_1, b) +// let _1 := 2 +// let b := mload(_1) +// if calldataload(1) +// { +// mstore(_1, 7) +// mstore(_1, b) +// } +// sstore(0, b) // } -// sstore(0, b) // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/merge_mload_without_rewrite.yul b/test/libyul/yulOptimizerTests/loadResolver/merge_mload_without_rewrite.yul index f6d0bdc7d1..7606416982 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/merge_mload_without_rewrite.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/merge_mload_without_rewrite.yul @@ -10,10 +10,12 @@ // step: loadResolver // // { -// let _1 := 2 -// let b := mload(_1) -// let _2 := 0 -// sstore(_2, b) -// if calldataload(1) { mstore(_1, 7) } -// sstore(_2, mload(_1)) +// { +// let _1 := 2 +// let b := mload(_1) +// let _2 := 0 +// sstore(_2, b) +// if calldataload(1) { mstore(_1, 7) } +// sstore(_2, mload(_1)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/merge_unknown_write.yul b/test/libyul/yulOptimizerTests/loadResolver/merge_unknown_write.yul index 225e0f6272..e8cc3cf4b0 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/merge_unknown_write.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/merge_unknown_write.yul @@ -11,12 +11,14 @@ // step: loadResolver // // { -// let _2 := calldataload(10) -// let _3 := 0 -// let _4 := calldataload(_3) -// mstore(_4, _2) -// let _5 := 1 -// if calldataload(_5) { mstore(_3, _5) } -// let t := mload(_3) -// sstore(t, mload(_4)) +// { +// let _2 := calldataload(10) +// let _3 := 0 +// let _4 := calldataload(_3) +// mstore(_4, _2) +// let _5 := 1 +// if calldataload(_5) { mstore(_3, _5) } +// let t := mload(_3) +// sstore(t, mload(_4)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/merge_with_rewrite.yul b/test/libyul/yulOptimizerTests/loadResolver/merge_with_rewrite.yul index b4b113e812..c6c76f425f 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/merge_with_rewrite.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/merge_with_rewrite.yul @@ -11,13 +11,15 @@ // step: loadResolver // // { -// let _1 := 3 -// let _2 := 2 -// mstore(_2, _1) -// if calldataload(1) // { -// mstore(_2, 7) +// let _1 := 3 +// let _2 := 2 // mstore(_2, _1) +// if calldataload(1) +// { +// mstore(_2, 7) +// mstore(_2, _1) +// } +// sstore(0, _1) // } -// sstore(0, _1) // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/mload_in_function.yul b/test/libyul/yulOptimizerTests/loadResolver/mload_in_function.yul index a8d9e2af06..b76d071ae8 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/mload_in_function.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/mload_in_function.yul @@ -10,11 +10,13 @@ // step: loadResolver // // { -// let _1 := 1337 -// let _2 := 0 -// mstore(_2, _1) -// foo(42) -// sstore(_2, mload(_2)) +// { +// let _1 := 1337 +// let _2 := 0 +// mstore(_2, _1) +// foo(42) +// sstore(_2, mload(_2)) +// } // function foo(x) // { // for { } diff --git a/test/libyul/yulOptimizerTests/loadResolver/mload_self.yul b/test/libyul/yulOptimizerTests/loadResolver/mload_self.yul index e299bcbb9f..6ad9d36ac7 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/mload_self.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/mload_self.yul @@ -8,8 +8,10 @@ // step: loadResolver // // { -// let _1 := 0 -// let x := calldataload(_1) -// x := mload(x) -// sstore(_1, mload(x)) +// { +// let _1 := 0 +// let x := calldataload(_1) +// x := mload(x) +// sstore(_1, mload(x)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/mstore_in_function_loop_body.yul b/test/libyul/yulOptimizerTests/loadResolver/mstore_in_function_loop_body.yul index 6fcf7a6aa8..901ea12efc 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/mstore_in_function_loop_body.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/mstore_in_function_loop_body.yul @@ -15,11 +15,13 @@ // step: loadResolver // // { -// let _1 := 1337 -// let _2 := 0 -// mstore(_2, _1) -// funcWithLoop(42) -// sstore(_2, mload(_2)) +// { +// let _1 := 1337 +// let _2 := 0 +// mstore(_2, _1) +// funcWithLoop(42) +// sstore(_2, mload(_2)) +// } // function userNot(x) -> y // { y := iszero(x) } // function funcWithLoop(x_1) diff --git a/test/libyul/yulOptimizerTests/loadResolver/mstore_in_function_loop_init.yul b/test/libyul/yulOptimizerTests/loadResolver/mstore_in_function_loop_init.yul index 4794237d67..6fb0fdcba9 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/mstore_in_function_loop_init.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/mstore_in_function_loop_init.yul @@ -15,11 +15,13 @@ // step: loadResolver // // { -// let _1 := 1337 -// let _2 := 0 -// mstore(_2, _1) -// funcWithLoop(42) -// sstore(_2, mload(_2)) +// { +// let _1 := 1337 +// let _2 := 0 +// mstore(_2, _1) +// funcWithLoop(42) +// sstore(_2, mload(_2)) +// } // function userNot(x) -> y // { y := iszero(x) } // function funcWithLoop(x_1) diff --git a/test/libyul/yulOptimizerTests/loadResolver/multi_sload_loop.yul b/test/libyul/yulOptimizerTests/loadResolver/multi_sload_loop.yul index 9aecad5290..c367059eb9 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/multi_sload_loop.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/multi_sload_loop.yul @@ -14,17 +14,19 @@ // step: loadResolver // // { -// let _1 := 0 -// let x := calldataload(_1) -// let len := sload(x) -// let sum -// let i := _1 -// for { } lt(i, len) { i := add(i, 1) } // { -// let p := add(add(x, i), 1) -// if gt(p, len) { revert(_1, _1) } -// sum := add(sum, sload(p)) +// let _1 := 0 +// let x := calldataload(_1) +// let len := sload(x) +// let sum +// let i := _1 +// for { } lt(i, len) { i := add(i, 1) } +// { +// let p := add(add(x, i), 1) +// if gt(p, len) { revert(_1, _1) } +// sum := add(sum, sload(p)) +// } +// mstore(_1, sum) +// return(_1, 0x20) // } -// mstore(_1, sum) -// return(_1, 0x20) // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/re_store_memory.yul b/test/libyul/yulOptimizerTests/loadResolver/re_store_memory.yul index 01e29b705e..031a5f22a5 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/re_store_memory.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/re_store_memory.yul @@ -11,11 +11,13 @@ // step: loadResolver // // { -// let a := 0 -// let b := 1 -// let c := 2 -// mstore(a, b) -// sstore(a, b) -// mstore(a, c) -// sstore(10, c) +// { +// let a := 0 +// let b := 1 +// let c := 2 +// mstore(a, b) +// sstore(a, b) +// mstore(a, c) +// sstore(10, c) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/re_store_storage.yul b/test/libyul/yulOptimizerTests/loadResolver/re_store_storage.yul index 8c33e4f5dc..fab562208b 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/re_store_storage.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/re_store_storage.yul @@ -11,11 +11,13 @@ // step: loadResolver // // { -// let a := 0 -// let b := 1 -// let c := 2 -// sstore(a, b) -// mstore(a, b) -// sstore(a, c) -// mstore(32, c) +// { +// let a := 0 +// let b := 1 +// let c := 2 +// sstore(a, b) +// mstore(a, b) +// sstore(a, c) +// mstore(32, c) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/reassign.yul b/test/libyul/yulOptimizerTests/loadResolver/reassign.yul index 4687422e92..694b59e262 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/reassign.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/reassign.yul @@ -8,9 +8,11 @@ // step: loadResolver // // { -// let _1 := 0 -// let a := calldataload(_1) -// sstore(a, 6) -// a := calldataload(2) -// mstore(_1, sload(a)) +// { +// let _1 := 0 +// let a := calldataload(_1) +// sstore(a, 6) +// a := calldataload(2) +// mstore(_1, sload(a)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/reassign_value_expression.yul b/test/libyul/yulOptimizerTests/loadResolver/reassign_value_expression.yul index 1b73cecb93..402987acb4 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/reassign_value_expression.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/reassign_value_expression.yul @@ -18,15 +18,17 @@ // step: loadResolver // // { -// let x := calldataload(1) -// let a := add(x, 10) -// let _3 := 7 -// sstore(a, _3) -// x := 9 -// let _4 := 11 -// mstore(_3, _4) -// a := 33 -// mstore(sload(a), _4) -// a := 39 -// mstore(sload(a), _4) +// { +// let x := calldataload(1) +// let a := add(x, 10) +// let _3 := 7 +// sstore(a, _3) +// x := 9 +// let _4 := 11 +// mstore(_3, _4) +// a := 33 +// mstore(sload(a), _4) +// a := 39 +// mstore(sload(a), _4) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/second_mstore_with_delta.yul b/test/libyul/yulOptimizerTests/loadResolver/second_mstore_with_delta.yul index 1aa05106c3..8f1cf338f6 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/second_mstore_with_delta.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/second_mstore_with_delta.yul @@ -13,12 +13,14 @@ // step: loadResolver // // { -// let x := calldataload(1) -// let a := add(x, 10) -// let b := add(x, 42) -// let _4 := 7 -// mstore(a, _4) -// let _5 := 8 -// mstore(b, _5) -// sstore(_4, _5) +// { +// let x := calldataload(1) +// let a := add(x, 10) +// let b := add(x, 42) +// let _4 := 7 +// mstore(a, _4) +// let _5 := 8 +// mstore(b, _5) +// sstore(_4, _5) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/second_store.yul b/test/libyul/yulOptimizerTests/loadResolver/second_store.yul index f6f8250ce0..eb960a9f6e 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/second_store.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/second_store.yul @@ -10,10 +10,12 @@ // step: loadResolver // // { -// let x := calldataload(1) -// sstore(x, 7) -// let _3 := 6 -// let _4 := 0 -// sstore(calldataload(_4), _3) -// mstore(_4, sload(x)) +// { +// let x := calldataload(1) +// sstore(x, 7) +// let _3 := 6 +// let _4 := 0 +// sstore(calldataload(_4), _3) +// mstore(_4, sload(x)) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/second_store_same_value.yul b/test/libyul/yulOptimizerTests/loadResolver/second_store_same_value.yul index a5cb459ad7..e13b8aa5f6 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/second_store_same_value.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/second_store_same_value.yul @@ -10,10 +10,12 @@ // step: loadResolver // // { -// let x := calldataload(1) -// let _2 := 7 -// sstore(x, _2) -// let _4 := 0 -// sstore(calldataload(_4), _2) -// mstore(_4, _2) +// { +// let x := calldataload(1) +// let _2 := 7 +// sstore(x, _2) +// let _4 := 0 +// sstore(calldataload(_4), _2) +// mstore(_4, _2) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/second_store_with_delta.yul b/test/libyul/yulOptimizerTests/loadResolver/second_store_with_delta.yul index c2e669b7f6..f301737eca 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/second_store_with_delta.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/second_store_with_delta.yul @@ -13,12 +13,14 @@ // step: loadResolver // // { -// let x := calldataload(1) -// let a := add(x, 10) -// let b := add(x, 20) -// let _4 := 7 -// sstore(a, _4) -// let _5 := 8 -// sstore(b, _5) -// mstore(_4, _5) +// { +// let x := calldataload(1) +// let a := add(x, 10) +// let b := add(x, 20) +// let _4 := 7 +// sstore(a, _4) +// let _5 := 8 +// sstore(b, _5) +// mstore(_4, _5) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/side_effects_of_user_functions.yul b/test/libyul/yulOptimizerTests/loadResolver/side_effects_of_user_functions.yul index 684e6b94f1..b1eefd0890 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/side_effects_of_user_functions.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/side_effects_of_user_functions.yul @@ -12,15 +12,17 @@ // step: loadResolver // // { -// let _1 := 9 -// let _2 := 2 -// mstore(_2, _1) -// reads() -// let _4 := _1 -// let _5 := 0 -// sstore(_5, _4) -// stores() -// sstore(_5, mload(_2)) +// { +// let _1 := 9 +// let _2 := 2 +// mstore(_2, _1) +// reads() +// let _4 := _1 +// let _5 := 0 +// sstore(_5, _4) +// stores() +// sstore(_5, mload(_2)) +// } // function stores() // { mstore(0, 1) } // function reads() diff --git a/test/libyul/yulOptimizerTests/loadResolver/simple.yul b/test/libyul/yulOptimizerTests/loadResolver/simple.yul index a645f1692f..a20025bcdf 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/simple.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/simple.yul @@ -8,7 +8,9 @@ // step: loadResolver // // { -// let _2 := calldataload(10) -// sstore(calldataload(0), _2) -// mstore(sload(_2), _2) +// { +// let _2 := calldataload(10) +// sstore(calldataload(0), _2) +// mstore(sload(_2), _2) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/simple_memory.yul b/test/libyul/yulOptimizerTests/loadResolver/simple_memory.yul index 667abe053c..3aa1d740f4 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/simple_memory.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/simple_memory.yul @@ -8,7 +8,9 @@ // step: loadResolver // // { -// let _2 := calldataload(10) -// mstore(calldataload(0), _2) -// sstore(mload(_2), _2) +// { +// let _2 := calldataload(10) +// mstore(calldataload(0), _2) +// sstore(mload(_2), _2) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/staticcall.yul b/test/libyul/yulOptimizerTests/loadResolver/staticcall.yul index b24ab0170c..2a72eee3e2 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/staticcall.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/staticcall.yul @@ -15,14 +15,16 @@ // step: loadResolver // // { -// let a := 0 -// let b := 1 -// sstore(a, b) -// let _1 := 7 -// let _2 := 900 -// mstore(_2, _1) -// let _3 := 200 -// pop(staticcall(10000, 10, a, _3, a, _3)) -// sstore(1, mload(_2)) -// mstore(a, b) +// { +// let a := 0 +// let b := 1 +// sstore(a, b) +// let _1 := 7 +// let _2 := 900 +// mstore(_2, _1) +// let _3 := 200 +// pop(staticcall(10000, 10, a, _3, a, _3)) +// sstore(1, mload(_2)) +// mstore(a, b) +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/verbatim_mload.yul b/test/libyul/yulOptimizerTests/loadResolver/verbatim_mload.yul index 150c0240b5..8d417a1776 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/verbatim_mload.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/verbatim_mload.yul @@ -8,9 +8,11 @@ // step: loadResolver // // { -// let _1 := 20 -// let _2 := 10 -// mstore(_2, _1) -// sstore(0, mload(_2)) -// verbatim_0i_0o("test") +// { +// let _1 := 20 +// let _2 := 10 +// mstore(_2, _1) +// sstore(0, mload(_2)) +// verbatim_0i_0o("test") +// } // } diff --git a/test/libyul/yulOptimizerTests/loadResolver/verbatim_sload.yul b/test/libyul/yulOptimizerTests/loadResolver/verbatim_sload.yul index ba9cb32d80..81479a5092 100644 --- a/test/libyul/yulOptimizerTests/loadResolver/verbatim_sload.yul +++ b/test/libyul/yulOptimizerTests/loadResolver/verbatim_sload.yul @@ -10,12 +10,14 @@ // step: loadResolver // // { -// let _1 := 20 -// let _2 := 10 -// sstore(_2, _1) -// let _4 := _1 -// let _5 := 30 -// sstore(_5, _4) -// verbatim_0i_0o("test") -// sstore(_5, sload(_2)) +// { +// let _1 := 20 +// let _2 := 10 +// sstore(_2, _1) +// let _4 := _1 +// let _5 := 30 +// sstore(_5, _4) +// verbatim_0i_0o("test") +// sstore(_5, sload(_2)) +// } // } diff --git a/test/libyul/yulOptimizerTests/splitJoin/control_flow.yul b/test/libyul/yulOptimizerTests/splitJoin/control_flow.yul index c8b22424cc..875bececd6 100644 --- a/test/libyul/yulOptimizerTests/splitJoin/control_flow.yul +++ b/test/libyul/yulOptimizerTests/splitJoin/control_flow.yul @@ -10,12 +10,14 @@ // step: splitJoin // // { -// if mul(add(calldataload(0), 2), 3) // { -// for { let a := 2 } lt(a, mload(a)) { a := add(a, mul(a, 2)) } +// if mul(add(calldataload(0), 2), 3) // { -// let b := mul(add(a, 2), 4) -// sstore(b, mul(b, 2)) +// for { let a := 2 } lt(a, mload(a)) { a := add(a, mul(a, 2)) } +// { +// let b := mul(add(a, 2), 4) +// sstore(b, mul(b, 2)) +// } // } // } // } diff --git a/test/libyul/yulOptimizerTests/splitJoin/functions.yul b/test/libyul/yulOptimizerTests/splitJoin/functions.yul index e2f554dd0e..08e741e8e9 100644 --- a/test/libyul/yulOptimizerTests/splitJoin/functions.yul +++ b/test/libyul/yulOptimizerTests/splitJoin/functions.yul @@ -12,14 +12,16 @@ // step: splitJoin // // { -// let x := f(0) -// function f(y) -> r // { -// r := mload(mul(6, add(y, 0x20))) +// let x := f(0) +// for { let a := 2 } lt(a, mload(a)) { a := add(a, mul(a, 2)) } +// { +// let b := mul(add(a, f(a)), 4) +// sstore(b, mul(b, 2)) +// } // } -// for { let a := 2 } lt(a, mload(a)) { a := add(a, mul(a, 2)) } +// function f(y) -> r // { -// let b := mul(add(a, f(a)), 4) -// sstore(b, mul(b, 2)) +// r := mload(mul(6, add(y, 0x20))) // } // } diff --git a/test/libyul/yulOptimizerTests/splitJoin/smoke.yul b/test/libyul/yulOptimizerTests/splitJoin/smoke.yul index 4aac31ddb6..86e53ab148 100644 --- a/test/libyul/yulOptimizerTests/splitJoin/smoke.yul +++ b/test/libyul/yulOptimizerTests/splitJoin/smoke.yul @@ -2,4 +2,4 @@ // ---- // step: splitJoin // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/for_loop.yul b/test/libyul/yulOptimizerTests/ssaAndBack/for_loop.yul index 43b9ade6a0..19b3ba44ea 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/for_loop.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/for_loop.yul @@ -19,12 +19,14 @@ // step: ssaAndBack // // { -// let a := mload(0) -// let b := mload(1) -// for { } lt(mload(a), mload(b)) { a := mload(b) } // { -// let b_4 := mload(a) -// a := mload(b_4) -// b := mload(a) +// let a := mload(0) +// let b := mload(1) +// for { } lt(mload(a), mload(b)) { a := mload(b) } +// { +// let b_4 := mload(a) +// a := mload(b_4) +// b := mload(a) +// } // } // } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign.yul b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign.yul index 2e818561c6..1bfd89cd83 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign.yul @@ -10,6 +10,8 @@ // step: ssaAndBack // // { -// let a_5 := mload(4) -// mstore(a_5, 0) +// { +// let a_5 := mload(4) +// mstore(a_5, 0) +// } // } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_if.yul b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_if.yul index 4815349d7d..c0f3a4242a 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_if.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_if.yul @@ -12,7 +12,9 @@ // step: ssaAndBack // // { -// let a := mload(0) -// if mload(1) { a := mload(3) } -// mstore(a, 0) +// { +// let a := mload(0) +// if mload(1) { a := mload(3) } +// mstore(a, 0) +// } // } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_if.yul b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_if.yul index a0821ab373..e3a6710282 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_if.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_if.yul @@ -13,14 +13,16 @@ // step: ssaAndBack // // { -// let a := mload(0) -// let b := mload(1) -// if mload(2) // { -// let a_3 := mload(b) -// let b_4 := mload(a_3) -// a := mload(b_4) -// b := mload(a) +// let a := mload(0) +// let b := mload(1) +// if mload(2) +// { +// let a_3 := mload(b) +// let b_4 := mload(a_3) +// a := mload(b_4) +// b := mload(a) +// } +// mstore(a, b) // } -// mstore(a, b) // } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_switch.yul b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_switch.yul index 92a0ba8259..89f3acaa63 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_switch.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_switch.yul @@ -20,20 +20,22 @@ // step: ssaAndBack // // { -// let a := mload(0) -// let b := mload(1) -// switch mload(2) -// case 0 { -// let a_3 := mload(b) -// let b_4 := mload(a_3) -// a := mload(b_4) -// b := mload(a) +// { +// let a := mload(0) +// let b := mload(1) +// switch mload(2) +// case 0 { +// let a_3 := mload(b) +// let b_4 := mload(a_3) +// a := mload(b_4) +// b := mload(a) +// } +// default { +// let b_7 := mload(a) +// let a_8 := mload(b_7) +// b := mload(a_8) +// a := mload(b) +// } +// mstore(a, b) // } -// default { -// let b_7 := mload(a) -// let a_8 := mload(b_7) -// b := mload(a_8) -// a := mload(b) -// } -// mstore(a, b) // } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_switch.yul b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_switch.yul index 63c4f8561e..b210c09c0e 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_switch.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_switch.yul @@ -17,9 +17,11 @@ // step: ssaAndBack // // { -// let a := mload(0) -// switch mload(1) -// case 0 { a := mload(3) } -// default { a := mload(6) } -// mstore(a, 0) +// { +// let a := mload(0) +// switch mload(1) +// case 0 { a := mload(3) } +// default { a := mload(6) } +// mstore(a, 0) +// } // } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/simple.yul b/test/libyul/yulOptimizerTests/ssaAndBack/simple.yul index e2f130507a..b2979e76d2 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/simple.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/simple.yul @@ -7,6 +7,8 @@ // step: ssaAndBack // // { -// let a_2 := mload(1) -// mstore(a_2, 0) +// { +// let a_2 := mload(1) +// mstore(a_2, 0) +// } // } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_if.yul b/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_if.yul index e2516b45b9..71823f105a 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_if.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_if.yul @@ -10,7 +10,9 @@ // step: ssaAndBack // // { -// let a := mload(0) -// if mload(1) { a := mload(1) } -// mstore(a, 0) +// { +// let a := mload(0) +// if mload(1) { a := mload(1) } +// mstore(a, 0) +// } // } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_switch.yul b/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_switch.yul index e6e0553c18..8c53bd28ab 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_switch.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_switch.yul @@ -13,9 +13,11 @@ // step: ssaAndBack // // { -// let a := mload(0) -// switch mload(1) -// case 0 { a := mload(1) } -// default { a := mload(2) } -// mstore(a, 0) +// { +// let a := mload(0) +// switch mload(1) +// case 0 { a := mload(1) } +// default { a := mload(2) } +// mstore(a, 0) +// } // } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/ssaReverse.yul b/test/libyul/yulOptimizerTests/ssaAndBack/ssaReverse.yul index 0ef0ffee39..21dfdf2cee 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/ssaReverse.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/ssaReverse.yul @@ -24,8 +24,10 @@ // step: ssaAndBack // // { -// let a, b := abi_decode_t_bytes_calldata_ptr(mload(0), mload(1)) -// mstore(a, b) +// { +// let a, b := abi_decode_t_bytes_calldata_ptr(mload(0), mload(1)) +// mstore(a, b) +// } // function abi_decode_t_bytes_calldata_ptr(offset_12, end_13) -> arrayPos_14, length_15 // { // if iszero(slt(add(offset_12, 0x1f), end_13)) { revert(0, 0) } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/two_vars.yul b/test/libyul/yulOptimizerTests/ssaAndBack/two_vars.yul index 6053bd9ac9..1205993567 100644 --- a/test/libyul/yulOptimizerTests/ssaAndBack/two_vars.yul +++ b/test/libyul/yulOptimizerTests/ssaAndBack/two_vars.yul @@ -11,11 +11,13 @@ // step: ssaAndBack // // { -// let a_1 := mload(0) -// let b_2 := mload(a_1) -// let a_3 := mload(b_2) -// let b_4 := mload(a_3) -// let a_5 := mload(b_4) -// let b_6 := mload(a_5) -// mstore(a_5, b_6) +// { +// let a_1 := mload(0) +// let b_2 := mload(a_1) +// let a_3 := mload(b_2) +// let b_4 := mload(a_3) +// let a_5 := mload(b_4) +// let b_6 := mload(a_5) +// mstore(a_5, b_6) +// } // } diff --git a/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul b/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul index 382bd201d6..3633b3f36c 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/inlineInBlock.yul @@ -9,5 +9,7 @@ // step: stackCompressor // // { -// mstore(calldataload(calldataload(9)), add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(calldataload(calldataload(9)), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)) +// { +// mstore(calldataload(calldataload(9)), add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(calldataload(calldataload(9)), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)) +// } // } diff --git a/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul b/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul index ed85fe7b85..35dfa5343d 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/inlineInFunction.yul @@ -11,7 +11,7 @@ // step: stackCompressor // // { -// let x := 8 +// { let x := 8 } // function f() // { // mstore(calldataload(calldataload(9)), add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(calldataload(calldataload(9)), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)) diff --git a/test/libyul/yulOptimizerTests/stackCompressor/noInline.yul b/test/libyul/yulOptimizerTests/stackCompressor/noInline.yul index b5f3dd8725..1a178abf09 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/noInline.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/noInline.yul @@ -6,7 +6,7 @@ // step: stackCompressor // // { -// let x := 8 +// { let x := 8 } // function f() // { let y := 9 } // } diff --git a/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul b/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul index dc10737ad9..0556a22202 100644 --- a/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul +++ b/test/libyul/yulOptimizerTests/stackCompressor/unusedPrunerWithMSize.yul @@ -24,15 +24,17 @@ // step: stackCompressor // // { -// let _17_72 := msize() -// let _22_75 := msize() -// let _25_76 := msize() -// let _30_80 := msize() -// let _32_81 := msize() -// pop(keccak256(1, 2)) -// let _105 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -// mstore(lt(or(gt(1, or(or(gt(or(or(or(gt(or(gt(_105, _32_81), 1), _30_80), lt(or(1, add(_25_76, _105)), 1)), _22_75), 1), 1), gt(not(_17_72), 1)), 1)), 1), 1), 1) -// foo_singlereturn_1() +// { +// let _17_72 := msize() +// let _22_75 := msize() +// let _25_76 := msize() +// let _30_80 := msize() +// let _32_81 := msize() +// pop(keccak256(1, 2)) +// let _105 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// mstore(lt(or(gt(1, or(or(gt(or(or(or(gt(or(gt(_105, _32_81), 1), _30_80), lt(or(1, add(_25_76, _105)), 1)), _22_75), 1), 1), gt(not(_17_72), 1)), 1)), 1), 1), 1) +// foo_singlereturn_1() +// } // function foo_singlereturn_1() // { extcodecopy(1, msize(), 1, 1) } // } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/functions.yul b/test/libyul/yulOptimizerTests/unusedPruner/functions.yul index cceace3bbb..cafb399f61 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/functions.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/functions.yul @@ -5,4 +5,4 @@ // ---- // step: unusedPruner // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/intermediate_assignment.yul b/test/libyul/yulOptimizerTests/unusedPruner/intermediate_assignment.yul index 32e96b9f3a..00bb145adb 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/intermediate_assignment.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/intermediate_assignment.yul @@ -7,6 +7,8 @@ // step: unusedPruner // // { -// let a := 1 -// a := 4 +// { +// let a := 1 +// a := 4 +// } // } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/intermediate_multi_assignment.yul b/test/libyul/yulOptimizerTests/unusedPruner/intermediate_multi_assignment.yul index bc05f09f8a..4132a93f85 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/intermediate_multi_assignment.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/intermediate_multi_assignment.yul @@ -8,9 +8,11 @@ // step: unusedPruner // // { -// let a, b +// { +// let a, b +// a := f() +// b := 1 +// } // function f() -> x // { } -// a := f() -// b := 1 // } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/keccak.yul b/test/libyul/yulOptimizerTests/unusedPruner/keccak.yul index 6ad93184a6..357b3a33cf 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/keccak.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/keccak.yul @@ -7,6 +7,8 @@ // step: unusedPruner // // { -// pop(keccak256(1, 1)) -// sstore(0, msize()) +// { +// pop(keccak256(1, 1)) +// sstore(0, msize()) +// } // } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/movable_user_defined_function.yul b/test/libyul/yulOptimizerTests/unusedPruner/movable_user_defined_function.yul index 09d366fb29..43a4297cb5 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/movable_user_defined_function.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/movable_user_defined_function.yul @@ -10,4 +10,4 @@ // ---- // step: unusedPruner // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/msize.yul b/test/libyul/yulOptimizerTests/unusedPruner/msize.yul index 05ad7b743e..633b447cd9 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/msize.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/msize.yul @@ -7,6 +7,8 @@ // step: unusedPruner // // { -// pop(mload(10)) -// sstore(0, msize()) +// { +// pop(mload(10)) +// sstore(0, msize()) +// } // } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/multi_assign.yul b/test/libyul/yulOptimizerTests/unusedPruner/multi_assign.yul index 47e114373b..aac772dcb9 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/multi_assign.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/multi_assign.yul @@ -8,9 +8,11 @@ // step: unusedPruner // // { -// let a -// let b +// { +// let a +// let b +// a, b := f() +// } // function f() -> x, y // { } -// a, b := f() // } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/multi_assignments.yul b/test/libyul/yulOptimizerTests/unusedPruner/multi_assignments.yul index 86f175d695..a987efe800 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/multi_assignments.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/multi_assignments.yul @@ -7,7 +7,9 @@ // step: unusedPruner // // { -// let x, y -// x := 1 -// y := 2 +// { +// let x, y +// x := 1 +// y := 2 +// } // } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/multi_declarations.yul b/test/libyul/yulOptimizerTests/unusedPruner/multi_declarations.yul index f727b0e93c..3f70d6638a 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/multi_declarations.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/multi_declarations.yul @@ -4,4 +4,4 @@ // ---- // step: unusedPruner // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/multi_declare.yul b/test/libyul/yulOptimizerTests/unusedPruner/multi_declare.yul index aa8ae0ad4b..d65b4d5d7e 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/multi_declare.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/multi_declare.yul @@ -5,4 +5,4 @@ // ---- // step: unusedPruner // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/multi_partial_assignments.yul b/test/libyul/yulOptimizerTests/unusedPruner/multi_partial_assignments.yul index f54087a7d8..d66889a889 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/multi_partial_assignments.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/multi_partial_assignments.yul @@ -6,6 +6,8 @@ // step: unusedPruner // // { -// let x, y -// x := 1 +// { +// let x, y +// x := 1 +// } // } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/no_msize.yul b/test/libyul/yulOptimizerTests/unusedPruner/no_msize.yul index 7bfc4d7884..0591c0e2a6 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/no_msize.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/no_msize.yul @@ -6,4 +6,4 @@ // ---- // step: unusedPruner // -// { sstore(0, 5) } +// { { sstore(0, 5) } } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/pop.yul b/test/libyul/yulOptimizerTests/unusedPruner/pop.yul index 66d16db1ed..636552eee3 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/pop.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/pop.yul @@ -5,4 +5,4 @@ // ---- // step: unusedPruner // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/smoke.yul b/test/libyul/yulOptimizerTests/unusedPruner/smoke.yul index a2ac495a04..3315ce2c42 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/smoke.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/smoke.yul @@ -2,4 +2,4 @@ // ---- // step: unusedPruner // -// { } +// { { } } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/trivial.yul b/test/libyul/yulOptimizerTests/unusedPruner/trivial.yul index 9de594351b..8a47d21083 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/trivial.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/trivial.yul @@ -6,4 +6,4 @@ // ---- // step: unusedPruner // -// { mstore(0, 1) } +// { { mstore(0, 1) } } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/verbatim.yul b/test/libyul/yulOptimizerTests/unusedPruner/verbatim.yul index 65b464f7f5..7fea85c52c 100644 --- a/test/libyul/yulOptimizerTests/unusedPruner/verbatim.yul +++ b/test/libyul/yulOptimizerTests/unusedPruner/verbatim.yul @@ -11,7 +11,9 @@ // step: unusedPruner // // { -// pop(mload(10)) -// pop(keccak256(10, 32)) -// verbatim_0i_0o("test") +// { +// pop(mload(10)) +// pop(keccak256(10, 32)) +// verbatim_0i_0o("test") +// } // } diff --git a/test/yulPhaser/Program.cpp b/test/yulPhaser/Program.cpp index 8aa2479a21..2e91926d05 100644 --- a/test/yulPhaser/Program.cpp +++ b/test/yulPhaser/Program.cpp @@ -337,7 +337,10 @@ BOOST_AUTO_TEST_CASE(optimise) Block const& parentBlockAfter = program.ast(); BOOST_TEST(parentBlockAfter.statements.size() == 1); - BOOST_TEST(holds_alternative(parentBlockAfter.statements[0])); + BOOST_TEST(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_AUTO_TEST_CASE(output_operator) From fbc48e30292db668de3874bf0fc9a9e74e9f471b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 12:32:53 +0200 Subject: [PATCH 0110/1748] Extract helpers for managing steps in parallelized CircleCI jobs from soltest_all.sh --- .circleci/soltest_all.sh | 41 +++++++++++++++++++++++----------------- scripts/common.sh | 22 +++++++++++++++++++++ 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 353d81cd68..0c414593f3 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -28,27 +28,31 @@ set -e REPODIR="$(realpath "$(dirname "$0")"/..)" +# shellcheck source=scripts/common.sh +source "${REPODIR}/scripts/common.sh" + EVM_VALUES=(homestead byzantium constantinople petersburg istanbul berlin london) DEFAULT_EVM=london [[ " ${EVM_VALUES[*]} " =~ $DEFAULT_EVM ]] OPTIMIZE_VALUES=(0 1) STEPS=$(( 1 + ${#EVM_VALUES[@]} * ${#OPTIMIZE_VALUES[@]} )) -if (( CIRCLE_NODE_TOTAL )) && (( CIRCLE_NODE_TOTAL > 1 )) -then - RUN_STEPS=$(seq "$STEPS" | circleci tests split | xargs) -else - RUN_STEPS=$(seq "$STEPS" | xargs) -fi - -echo "Running steps $RUN_STEPS..." +RUN_STEPS=$(circleci_select_steps "$(seq "$STEPS")") +printTask "Running steps $RUN_STEPS..." STEP=1 # Run for ABI encoder v1, without SMTChecker tests. -[[ " $RUN_STEPS " == *" $STEP "* ]] && EVM="${DEFAULT_EVM}" OPTIMIZE=1 ABI_ENCODER_V1=1 BOOST_TEST_ARGS="-t !smtCheckerTests" "${REPODIR}/.circleci/soltest.sh" -STEP=$((STEP + 1)) +if circleci_step_selected "$RUN_STEPS" "$STEP" +then + EVM="${DEFAULT_EVM}" \ + OPTIMIZE=1 \ + ABI_ENCODER_V1=1 \ + BOOST_TEST_ARGS="-t !smtCheckerTests" \ + "${REPODIR}/.circleci/soltest.sh" +fi +((++STEP)) for OPTIMIZE in "${OPTIMIZE_VALUES[@]}" do @@ -63,13 +67,16 @@ do DISABLE_SMTCHECKER="" [ "${OPTIMIZE}" != "0" ] && DISABLE_SMTCHECKER="-t !smtCheckerTests" - [[ " $RUN_STEPS " == *" $STEP "* ]] && EVM="$EVM" OPTIMIZE="$OPTIMIZE" SOLTEST_FLAGS="$SOLTEST_FLAGS $ENFORCE_GAS_ARGS $EWASM_ARGS" BOOST_TEST_ARGS="-t !@nooptions $DISABLE_SMTCHECKER" "${REPODIR}/.circleci/soltest.sh" - STEP=$((STEP + 1)) + if circleci_step_selected "$RUN_STEPS" "$STEP" + then + EVM="$EVM" \ + OPTIMIZE="$OPTIMIZE" \ + SOLTEST_FLAGS="$SOLTEST_FLAGS $ENFORCE_GAS_ARGS $EWASM_ARGS" \ + BOOST_TEST_ARGS="-t !@nooptions $DISABLE_SMTCHECKER" \ + "${REPODIR}/.circleci/soltest.sh" + fi + ((++STEP)) done done -if ((STEP != STEPS + 1)) -then - echo "Step counter not properly adjusted!" >&2 - exit 1 -fi +((STEP == STEPS + 1)) || assertFail "Step counter not properly adjusted!" diff --git a/scripts/common.sh b/scripts/common.sh index 3e40754a61..d529b5bfc2 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -196,3 +196,25 @@ function safe_kill kill -9 "$PID" fi } + +function circleci_select_steps +{ + local all_steps="$1" + (( $# == 1 )) || assertFail + + if (( CIRCLE_NODE_TOTAL )) && (( CIRCLE_NODE_TOTAL > 1 )) + then + echo "$all_steps" | circleci tests split | xargs + else + echo "$all_steps" | xargs + fi +} + +function circleci_step_selected +{ + local selected_steps="$1" + local step="$2" + [[ $step != *" "* ]] || assertFail "Step names must not contain spaces." + + [[ " $selected_steps " == *" $step "* ]] || return 1 +} From 834f9d3a6ec00357efbb4e3b68813f281a71acff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 12:46:34 +0200 Subject: [PATCH 0111/1748] Parallelize external test runs on CircleCI --- .circleci/config.yml | 2 ++ test/externalTests/colony.sh | 6 +++++- test/externalTests/common.sh | 9 +++++++++ test/externalTests/ens.sh | 6 +++++- test/externalTests/gnosis-v2.sh | 6 +++++- test/externalTests/gnosis.sh | 6 +++++- test/externalTests/zeppelin.sh | 6 +++++- 7 files changed, 36 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 72434ea15c..02787debc4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -943,6 +943,8 @@ jobs: default: 14 docker: - image: circleci/node:<> + # NOTE: Each external test does 3 separate compile&test runs + parallelism: 3 environment: TERM: xterm COMPILE_ONLY: <> diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index e32385af65..3aaff44138 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -38,6 +38,10 @@ function colony_test local min_optimizer_level=3 local max_optimizer_level=3 + local selected_optimizer_levels + selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") + print_optimizer_levels_or_exit "$selected_optimizer_levels" + setup_solcjs "$DIR" "$SOLJSON" download_project "$repo" "$branch" "$DIR" @@ -54,7 +58,7 @@ function colony_test replace_version_pragmas force_solc_modules "${DIR}/solc" - for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + for level in $selected_optimizer_levels; do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn done } diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index dbda3c3f46..2519a0f878 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -24,6 +24,15 @@ set -e CURRENT_EVM_VERSION=london +function print_optimizer_levels_or_exit +{ + local selected_levels="$1" + + [[ $selected_levels != "" ]] || { printWarning "No steps to run. Exiting."; exit 0; } + + printLog "Selected optimizer levels: ${selected_levels}" +} + function verify_input { if [ ! -f "$1" ]; then diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index bbdc573e21..9fed91be1f 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -38,6 +38,10 @@ function ens_test local min_optimizer_level=1 local max_optimizer_level=3 + local selected_optimizer_levels + selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") + print_optimizer_levels_or_exit "$selected_optimizer_levels" + setup_solcjs "$DIR" "$SOLJSON" download_project "$repo" "$branch" "$DIR" @@ -52,7 +56,7 @@ function ens_test replace_version_pragmas force_solc_modules "${DIR}/solc" - for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + for level in $selected_optimizer_levels; do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn done } diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index d92bcc1868..439a3dd91f 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -39,6 +39,10 @@ function gnosis_safe_test local min_optimizer_level=2 local max_optimizer_level=3 + local selected_optimizer_levels + selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") + print_optimizer_levels_or_exit "$selected_optimizer_levels" + setup_solcjs "$DIR" "$SOLJSON" download_project "$repo" "$branch" "$DIR" @@ -53,7 +57,7 @@ function gnosis_safe_test replace_version_pragmas force_solc_modules "${DIR}/solc" - for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + for level in $selected_optimizer_levels; do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn done } diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index b6d9ab0bcb..32b76d9c90 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -38,6 +38,10 @@ function gnosis_safe_test local min_optimizer_level=2 local max_optimizer_level=3 + local selected_optimizer_levels + selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") + print_optimizer_levels_or_exit "$selected_optimizer_levels" + setup_solcjs "$DIR" "$SOLJSON" download_project "$repo" "$branch" "$DIR" @@ -51,7 +55,7 @@ function gnosis_safe_test replace_version_pragmas force_solc_modules "${DIR}/solc" - for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + for level in $selected_optimizer_levels; do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn done } diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 1e23bb7ae5..24e576b931 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -38,6 +38,10 @@ function zeppelin_test local min_optimizer_level=1 local max_optimizer_level=3 + local selected_optimizer_levels + selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") + print_optimizer_levels_or_exit "$selected_optimizer_levels" + setup_solcjs "$DIR" "$SOLJSON" download_project "$repo" "$branch" "$DIR" @@ -48,7 +52,7 @@ function zeppelin_test replace_version_pragmas force_solc_modules "${DIR}/solc" - for level in $(seq "$min_optimizer_level" "$max_optimizer_level"); do + for level in $selected_optimizer_levels; do truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn done } From cffb7fec27c5f884a9a775738f7ab58a9d6d9275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 9 Nov 2021 17:23:33 +0100 Subject: [PATCH 0112/1748] Set version to 0.8.11 --- CMakeLists.txt | 2 +- Changelog.md | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23c2f0e42e..e3dc030c13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.8.10") +set(PROJECT_VERSION "0.8.11") # OSX target needed in order to support std::visit set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) diff --git a/Changelog.md b/Changelog.md index ee463b25cd..79d5df058c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +### 0.8.11 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.8.10 (2021-11-09) Language Features: From 276d173e6840c4e9570412acc91685c0ebd738ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 12 Oct 2021 12:51:44 +0200 Subject: [PATCH 0113/1748] Document DEV_SIMPLE_EXCEPTION macro --- libsolutil/Exceptions.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libsolutil/Exceptions.h b/libsolutil/Exceptions.h index d83d8004b4..684c5a051a 100644 --- a/libsolutil/Exceptions.h +++ b/libsolutil/Exceptions.h @@ -56,6 +56,10 @@ struct Exception: virtual std::exception, virtual boost::exception ::boost::throw_line(__LINE__) \ ) +/// Defines an exception type that's meant to signal a specific condition and be caught rather than +/// unwind the stack all the way to the top-level exception handler and interrupt the program. +/// As such it does not carry a message - the code catching it is expected to handle it without +/// letting it escape. #define DEV_SIMPLE_EXCEPTION(X) struct X: virtual ::solidity::util::Exception { const char* what() const noexcept override { return #X; } } DEV_SIMPLE_EXCEPTION(InvalidAddress); From cda0d029bc54c80729ca44d4db01771e37df22ba Mon Sep 17 00:00:00 2001 From: neel iyer <33139997+spiyer99@users.noreply.github.com> Date: Sun, 15 Aug 2021 10:32:01 +1000 Subject: [PATCH 0114/1748] Define CommandLineError and a few exceptions derived from it --- solc/CMakeLists.txt | 1 + solc/Exceptions.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 solc/Exceptions.h diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index fe68d4eb99..8d9d2b364c 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -1,6 +1,7 @@ set(libsolcli_sources CommandLineInterface.cpp CommandLineInterface.h CommandLineParser.cpp CommandLineParser.h + Exceptions.h ) add_library(solcli ${libsolcli_sources}) diff --git a/solc/Exceptions.h b/solc/Exceptions.h new file mode 100644 index 0000000000..39a464b9e5 --- /dev/null +++ b/solc/Exceptions.h @@ -0,0 +1,34 @@ +/* + 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 +/** + * Exceptions used by the command-line interface. + */ + +#pragma once + +#include + +namespace solidity::frontend +{ + +struct CommandLineError: virtual util::Exception {}; +struct CommandLineExecutionError: virtual CommandLineError {}; +struct CommandLineValidationError: virtual CommandLineError {}; +struct CommandLineOutputError: virtual CommandLineError {}; + +} From 3f5471165fc30658fb1a1954dbfc7be662e9639c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 11 Oct 2021 13:48:03 +0200 Subject: [PATCH 0115/1748] CommandLineParser: Report errors by raising exceptions --- solc/CommandLineInterface.cpp | 13 +- solc/CommandLineParser.cpp | 392 +++++++++++++------------------- solc/CommandLineParser.h | 38 ++-- test/solc/CommandLineParser.cpp | 56 ++--- 4 files changed, 211 insertions(+), 288 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 1d069f9251..78e60ad0cb 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -23,6 +23,8 @@ */ #include +#include + #include "license.h" #include "solidity/BuildInfo.h" @@ -592,9 +594,16 @@ bool CommandLineInterface::parseArguments(int _argc, char const* const* _argv) return false; } - bool success = parser.parse(_argc, _argv); - if (!success) + try + { + parser.parse(_argc, _argv); + } + catch (CommandLineValidationError const& _exception) + { + serr() << _exception.what() << endl; return false; + } + m_hasOutput = m_hasOutput || parser.hasOutput(); m_options = parser.options(); diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 9356c96625..cdd74a2172 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -17,7 +17,11 @@ // SPDX-License-Identifier: GPL-3.0 #include + +#include + #include + #include #include @@ -131,6 +135,9 @@ static set const g_metadataHashArgs }; static map const g_inputModeName = { + {InputMode::Help, "help"}, + {InputMode::License, "license"}, + {InputMode::Version, "version"}, {InputMode::Compiler, "compiler"}, {InputMode::CompilerWithASTImport, "compiler (AST import)"}, {InputMode::Assembler, "assembler"}, @@ -138,15 +145,16 @@ static map const g_inputModeName = { {InputMode::Linker, "linker"}, }; -bool CommandLineParser::checkMutuallyExclusive(vector const& _optionNames) +void CommandLineParser::checkMutuallyExclusive(vector const& _optionNames) { if (countEnabledOptions(_optionNames) > 1) { - serr() << "The following options are mutually exclusive: " << joinOptionNames(_optionNames) << ". "; - serr() << "Select at most one." << endl; - return false; + solThrow( + CommandLineValidationError, + "The following options are mutually exclusive: " + joinOptionNames(_optionNames) + ". " + + "Select at most one." + ); } - return true; } bool CompilerOutputs::operator==(CompilerOutputs const& _other) const noexcept @@ -268,17 +276,15 @@ OptimiserSettings CommandLineOptions::optimiserSettings() const return settings; } -bool CommandLineParser::parse(int _argc, char const* const* _argv) +void CommandLineParser::parse(int _argc, char const* const* _argv) { m_hasOutput = false; - if (!parseArgs(_argc, _argv)) - return false; - - return processArgs(); + parseArgs(_argc, _argv); + processArgs(); } -bool CommandLineParser::parseInputPathsAndRemappings() +void CommandLineParser::parseInputPathsAndRemappings() { m_options.input.ignoreMissingFiles = (m_args.count(g_strIgnoreMissingFiles) > 0); @@ -289,17 +295,14 @@ bool CommandLineParser::parseInputPathsAndRemappings() { optional remapping = ImportRemapper::parseRemapping(positionalArg); if (!remapping.has_value()) - { - serr() << "Invalid remapping: \"" << positionalArg << "\"." << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid remapping: \"" + positionalArg + "\"."); if (m_options.input.mode == InputMode::StandardJson) - { - serr() << "Import remappings are not accepted on the command line in Standard JSON mode." << endl; - serr() << "Please put them under 'settings.remappings' in the JSON input." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Import remappings are not accepted on the command line in Standard JSON mode.\n" + "Please put them under 'settings.remappings' in the JSON input." + ); if (!remapping->target.empty()) { @@ -324,26 +327,24 @@ bool CommandLineParser::parseInputPathsAndRemappings() if (m_options.input.mode == InputMode::StandardJson) { if (m_options.input.paths.size() > 1 || (m_options.input.paths.size() == 1 && m_options.input.addStdin)) - { - serr() << "Too many input files for --" << g_strStandardJSON << "." << endl; - serr() << "Please either specify a single file name or provide its content on standard input." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Too many input files for --" + g_strStandardJSON + ".\n" + "Please either specify a single file name or provide its content on standard input." + ); else if (m_options.input.paths.size() == 0) // Standard JSON mode input used to be handled separately and zero files meant "read from stdin". // Keep it working that way for backwards-compatibility. m_options.input.addStdin = true; } else if (m_options.input.paths.size() == 0 && !m_options.input.addStdin) - { - serr() << "No input files given. If you wish to use the standard input please specify \"-\" explicitly." << endl; - return false; - } - - return true; + solThrow( + CommandLineValidationError, + "No input files given. If you wish to use the standard input please specify \"-\" explicitly." + ); } -bool CommandLineParser::parseLibraryOption(string const& _input) +void CommandLineParser::parseLibraryOption(string const& _input) { namespace fs = boost::filesystem; string data = _input; @@ -378,71 +379,71 @@ bool CommandLineParser::parseLibraryOption(string const& _input) { separator = lib.rfind(':'); if (separator == string::npos) - { - serr() << "Equal sign separator missing in library address specifier \"" << lib << "\"" << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Equal sign separator missing in library address specifier \"" + lib + "\"" + ); else isSeparatorEqualSign = false; // separator is colon } else if (lib.rfind('=') != lib.find('=')) - { - serr() << "Only one equal sign \"=\" is allowed in the address string \"" << lib << "\"." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Only one equal sign \"=\" is allowed in the address string \"" + lib + "\"." + ); string libName(lib.begin(), lib.begin() + static_cast(separator)); boost::trim(libName); if (m_options.linker.libraries.count(libName)) - { - serr() << "Address specified more than once for library \"" << libName << "\"." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Address specified more than once for library \"" + libName + "\"." + ); string addrString(lib.begin() + static_cast(separator) + 1, lib.end()); boost::trim(addrString); if (addrString.empty()) - { - serr() << "Empty address provided for library \"" << libName << "\"." << endl; - serr() << "Note that there should not be any whitespace after the " << (isSeparatorEqualSign ? "equal sign" : "colon") << "." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Empty address provided for library \"" + libName + "\".\n" + "Note that there should not be any whitespace after the " + + (isSeparatorEqualSign ? "equal sign" : "colon") + "." + ); if (addrString.substr(0, 2) == "0x") addrString = addrString.substr(2); else - { - serr() << "The address " << addrString << " is not prefixed with \"0x\"." << endl; - serr() << "Note that the address must be prefixed with \"0x\"." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "The address " + addrString + " is not prefixed with \"0x\".\n" + "Note that the address must be prefixed with \"0x\"." + ); if (addrString.length() != 40) - { - serr() << "Invalid length for address for library \"" << libName << "\": " << addrString.length() << " instead of 40 characters." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Invalid length for address for library \"" + libName + "\": " + + to_string(addrString.length()) + " instead of 40 characters." + ); if (!passesAddressChecksum(addrString, false)) - { - serr() << "Invalid checksum on address for library \"" << libName << "\": " << addrString << endl; - serr() << "The correct checksum is " << getChecksummedAddress(addrString) << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Invalid checksum on address for library \"" + libName + "\": " + addrString + "\n" + "The correct checksum is " + getChecksummedAddress(addrString) + ); bytes binAddr = fromHex(addrString); h160 address(binAddr, h160::AlignRight); if (binAddr.size() > 20 || address == h160()) - { - serr() << "Invalid address for library \"" << libName << "\": " << addrString << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Invalid address for library \"" + libName + "\": " + addrString + ); m_options.linker.libraries[libName] = address; } - - return true; } -bool CommandLineParser::parseOutputSelection() +void CommandLineParser::parseOutputSelection() { static auto outputSupported = [](InputMode _mode, string_view _outputName) { @@ -498,13 +499,11 @@ bool CommandLineParser::parseOutputSelection() unsupportedOutputs.push_back(optionName); if (!unsupportedOutputs.empty()) - { - serr() << "The following outputs are not supported in " << g_inputModeName.at(m_options.input.mode) << " mode: "; - serr() << joinOptionNames(unsupportedOutputs) << "."; - return false; - } - - return true; + solThrow( + CommandLineValidationError, + "The following outputs are not supported in " + g_inputModeName.at(m_options.input.mode) + " mode: " + + joinOptionNames(unsupportedOutputs) + "." + ); } po::options_description CommandLineParser::optionsDescription() @@ -843,7 +842,7 @@ po::positional_options_description CommandLineParser::positionalOptionsDescripti return filesPositions; } -bool CommandLineParser::parseArgs(int _argc, char const* const* _argv) +void CommandLineParser::parseArgs(int _argc, char const* const* _argv) { po::options_description allOptions = optionsDescription(); po::positional_options_description filesPositions = positionalOptionsDescription(); @@ -858,18 +857,15 @@ bool CommandLineParser::parseArgs(int _argc, char const* const* _argv) } catch (po::error const& _exception) { - serr() << _exception.what() << endl; - return false; + solThrow(CommandLineValidationError, _exception.what()); } po::notify(m_args); - - return true; } -bool CommandLineParser::processArgs() +void CommandLineParser::processArgs() { - if (!checkMutuallyExclusive({ + checkMutuallyExclusive({ g_strHelp, g_strLicense, g_strVersion, @@ -879,8 +875,7 @@ bool CommandLineParser::processArgs() g_strStrictAssembly, g_strYul, g_strImportAst, - })) - return false; + }); if (m_args.count(g_strHelp) > 0) m_options.input.mode = InputMode::Help; @@ -904,7 +899,7 @@ bool CommandLineParser::processArgs() m_options.input.mode == InputMode::License || m_options.input.mode == InputMode::Version ) - return true; + return; map> validOptionInputModeCombinations = { // TODO: This should eventually contain all options. @@ -919,13 +914,13 @@ bool CommandLineParser::processArgs() } if (!invalidOptionsForCurrentInputMode.empty()) - { - serr() << "The following options are not supported in the current input mode: " << joinOptionNames(invalidOptionsForCurrentInputMode) << endl; - return false; - } + solThrow( + CommandLineValidationError, + "The following options are not supported in the current input mode: " + + joinOptionNames(invalidOptionsForCurrentInputMode) + ); - if (!checkMutuallyExclusive({g_strColor, g_strNoColor})) - return false; + checkMutuallyExclusive({g_strColor, g_strNoColor}); array const conflictingWithStopAfter{ CompilerOutputs::componentName(&CompilerOutputs::binary), @@ -940,8 +935,7 @@ bool CommandLineParser::processArgs() }; for (auto& option: conflictingWithStopAfter) - if (!checkMutuallyExclusive({g_strStopAfter, option})) - return false; + checkMutuallyExclusive({g_strStopAfter, option}); if ( m_options.input.mode != InputMode::Compiler && @@ -950,23 +944,23 @@ bool CommandLineParser::processArgs() ) { if (!m_args[g_strOptimizeRuns].defaulted()) - { - serr() << "Option --" << g_strOptimizeRuns << " is only valid in compiler and assembler modes." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Option --" + g_strOptimizeRuns + " is only valid in compiler and assembler modes." + ); for (string const& option: {g_strOptimize, g_strNoOptimizeYul, g_strOptimizeYul, g_strYulOptimizations}) if (m_args.count(option) > 0) - { - serr() << "Option --" << option << " is only valid in compiler and assembler modes." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Option --" + option + " is only valid in compiler and assembler modes." + ); if (!m_args[g_strDebugInfo].defaulted()) - { - serr() << "Option --" << g_strDebugInfo << " is only valid in compiler and assembler modes." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Option --" + g_strDebugInfo + " is only valid in compiler and assembler modes." + ); } if (m_args.count(g_strColor) > 0) @@ -981,15 +975,15 @@ bool CommandLineParser::processArgs() string revertStringsString = m_args[g_strRevertStrings].as(); std::optional revertStrings = revertStringsFromString(revertStringsString); if (!revertStrings) - { - serr() << "Invalid option for --" << g_strRevertStrings << ": " << revertStringsString << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Invalid option for --" + g_strRevertStrings + ": " + revertStringsString + ); if (*revertStrings == RevertStrings::VerboseDebug) - { - serr() << "Only \"default\", \"strip\" and \"debug\" are implemented for --" << g_strRevertStrings << " for now." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "Only \"default\", \"strip\" and \"debug\" are implemented for --" + g_strRevertStrings + " for now." + ); m_options.output.revertStrings = *revertStrings; } @@ -998,20 +992,13 @@ bool CommandLineParser::processArgs() string optionValue = m_args[g_strDebugInfo].as(); m_options.output.debugInfoSelection = DebugInfoSelection::fromString(optionValue); if (!m_options.output.debugInfoSelection.has_value()) - { - serr() << "Invalid value for --" << g_strDebugInfo << " option: " << optionValue << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid value for --" + g_strDebugInfo + " option: " + optionValue); if (m_options.output.debugInfoSelection->snippet && !m_options.output.debugInfoSelection->location) - { - serr() << "To use 'snippet' with --" << g_strDebugInfo << " you must select also 'location'." << endl; - return false; - } + solThrow(CommandLineValidationError, "To use 'snippet' with --" + g_strDebugInfo + " you must select also 'location'."); } - if (!parseCombinedJsonOption()) - return false; + parseCombinedJsonOption(); if (m_args.count(g_strOutputDir)) m_options.output.dir = m_args.at(g_strOutputDir).as(); @@ -1028,8 +1015,7 @@ bool CommandLineParser::processArgs() m_options.formatting.json.indent = m_args[g_strJsonIndent].as(); } - if (!parseOutputSelection()) - return false; + parseOutputSelection(); m_options.compiler.estimateGas = (m_args.count(g_strGas) > 0); @@ -1039,18 +1025,13 @@ bool CommandLineParser::processArgs() if (m_args.count(g_strIncludePath) > 0) { if (m_options.input.basePath.empty()) - { - serr() << "--" << g_strIncludePath << " option requires a non-empty base path." << endl; - return false; - } + solThrow(CommandLineValidationError, "--" + g_strIncludePath + " option requires a non-empty base path."); for (string const& includePath: m_args[g_strIncludePath].as>()) { if (includePath.empty()) - { - serr() << "Empty values are not allowed in --" << g_strIncludePath << "." << endl; - return false; - } + solThrow(CommandLineValidationError, "Empty values are not allowed in --" + g_strIncludePath + "."); + m_options.input.includePaths.push_back(includePath); } } @@ -1066,37 +1047,29 @@ bool CommandLineParser::processArgs() if (m_args.count(g_strStopAfter)) { if (m_args[g_strStopAfter].as() != "parsing") - { - serr() << "Valid options for --" << g_strStopAfter << " are: \"parsing\".\n"; - return false; - } + solThrow(CommandLineValidationError, "Valid options for --" + g_strStopAfter + " are: \"parsing\".\n"); else m_options.output.stopAfter = CompilerStack::State::Parsed; } - if (!parseInputPathsAndRemappings()) - return false; + parseInputPathsAndRemappings(); if (m_options.input.mode == InputMode::StandardJson) - return true; + return; if (m_args.count(g_strLibraries)) for (string const& library: m_args[g_strLibraries].as>()) - if (!parseLibraryOption(library)) - return false; + parseLibraryOption(library); if (m_options.input.mode == InputMode::Linker) - return true; + return; if (m_args.count(g_strEVMVersion)) { string versionOptionStr = m_args[g_strEVMVersion].as(); std::optional versionOption = langutil::EVMVersion::fromString(versionOptionStr); if (!versionOption) - { - serr() << "Invalid option for --" << g_strEVMVersion << ": " << versionOptionStr << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid option for --" + g_strEVMVersion + ": " + versionOptionStr); m_options.output.evmVersion = *versionOption; } @@ -1109,10 +1082,7 @@ bool CommandLineParser::processArgs() { OptimiserSettings optimiserSettings = m_options.optimiserSettings(); if (!optimiserSettings.runYulOptimiser) - { - serr() << "--" << g_strYulOptimizations << " is invalid if Yul optimizer is disabled" << endl; - return false; - } + solThrow(CommandLineValidationError, "--" + g_strYulOptimizations + " is invalid if Yul optimizer is disabled"); try { @@ -1120,8 +1090,10 @@ bool CommandLineParser::processArgs() } catch (yul::OptimizerException const& _exception) { - serr() << "Invalid optimizer step sequence in --" << g_strYulOptimizations << ": " << _exception.what() << endl; - return false; + solThrow( + CommandLineValidationError, + "Invalid optimizer step sequence in --" + g_strYulOptimizations + ": " + _exception.what() + ); } m_options.optimizer.yulSteps = m_args[g_strYulOptimizations].as(); @@ -1142,12 +1114,11 @@ bool CommandLineParser::processArgs() auto optionEnabled = [&](string const& name){ return m_args.count(name) > 0; }; auto enabledOptions = nonAssemblyModeOptions | ranges::views::filter(optionEnabled) | ranges::to_vector; - serr() << "The following options are invalid in assembly mode: "; - serr() << joinOptionNames(enabledOptions) << "."; + string message = "The following options are invalid in assembly mode: " + joinOptionNames(enabledOptions) + "."; if (m_args.count(g_strOptimizeYul) || m_args.count(g_strNoOptimizeYul)) - serr() << " Optimization is disabled by default and can be enabled with --" << g_strOptimize << "." << endl; - serr() << endl; - return false; + message += " Optimization is disabled by default and can be enabled with --" + g_strOptimize + "."; + + solThrow(CommandLineValidationError, message); } // switch to assembly mode @@ -1163,10 +1134,7 @@ bool CommandLineParser::processArgs() else if (machine == g_strEwasm) m_options.assembly.targetMachine = Machine::Ewasm; else - { - serr() << "Invalid option for --" << g_strMachine << ": " << machine << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid option for --" + g_strMachine + ": " + machine); } if (m_options.assembly.targetMachine == Machine::Ewasm && m_options.assembly.inputLanguage == Input::StrictAssembly) m_options.assembly.inputLanguage = Input::Ewasm; @@ -1179,45 +1147,35 @@ bool CommandLineParser::processArgs() { m_options.assembly.inputLanguage = Input::Ewasm; if (m_options.assembly.targetMachine != Machine::Ewasm) - { - serr() << "If you select Ewasm as --" << g_strYulDialect << ", "; - serr() << "--" << g_strMachine << " has to be Ewasm as well." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "If you select Ewasm as --" + g_strYulDialect + ", " + "--" + g_strMachine + " has to be Ewasm as well." + ); } else - { - serr() << "Invalid option for --" << g_strYulDialect << ": " << dialect << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid option for --" + g_strYulDialect + ": " + dialect); } if (m_options.optimizer.enabled && (m_options.assembly.inputLanguage != Input::StrictAssembly && m_options.assembly.inputLanguage != Input::Ewasm)) - { - serr() << - "Optimizer can only be used for strict assembly. Use --" << - g_strStrictAssembly << - "." << - endl; - return false; - } + solThrow( + CommandLineValidationError, + "Optimizer can only be used for strict assembly. Use --" + g_strStrictAssembly + "." + ); if (m_options.assembly.targetMachine == Machine::Ewasm && m_options.assembly.inputLanguage != Input::StrictAssembly && m_options.assembly.inputLanguage != Input::Ewasm) - { - serr() << "The selected input language is not directly supported when targeting the Ewasm machine "; - serr() << "and automatic translation is not available." << endl; - return false; - } - serr() << - "Warning: Yul is still experimental. Please use the output with care." << - endl; - - return true; + solThrow( + CommandLineValidationError, + "The selected input language is not directly supported when targeting the Ewasm machine " + "and automatic translation is not available." + ); + + serr() << "Warning: Yul is still experimental. Please use the output with care." << endl; + return; } else if (countEnabledOptions({g_strYulDialect, g_strMachine}) >= 1) - { - serr() << "--" << g_strYulDialect << " and --" << g_strMachine << " "; - serr() << "are only valid in assembly mode." << endl; - return false; - } + solThrow( + CommandLineValidationError, + "--" + g_strYulDialect + " and --" + g_strMachine + " are only valid in assembly mode." + ); if (m_args.count(g_strMetadataHash)) { @@ -1229,10 +1187,7 @@ bool CommandLineParser::processArgs() else if (hashStr == g_strNone) m_options.metadata.hash = CompilerStack::MetadataHash::None; else - { - serr() << "Invalid option for --" << g_strMetadataHash << ": " << hashStr << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid option for --" + g_strMetadataHash + ": " + hashStr); } if (m_args.count(g_strModelCheckerContracts)) @@ -1240,10 +1195,7 @@ bool CommandLineParser::processArgs() string contractsStr = m_args[g_strModelCheckerContracts].as(); optional contracts = ModelCheckerContracts::fromString(contractsStr); if (!contracts) - { - serr() << "Invalid option for --" << g_strModelCheckerContracts << ": " << contractsStr << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid option for --" + g_strModelCheckerContracts + ": " + contractsStr); m_options.modelChecker.settings.contracts = move(*contracts); } @@ -1255,10 +1207,7 @@ bool CommandLineParser::processArgs() string engineStr = m_args[g_strModelCheckerEngine].as(); optional engine = ModelCheckerEngine::fromString(engineStr); if (!engine) - { - serr() << "Invalid option for --" << g_strModelCheckerEngine << ": " << engineStr << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid option for --" + g_strModelCheckerEngine + ": " + engineStr); m_options.modelChecker.settings.engine = *engine; } @@ -1267,10 +1216,7 @@ bool CommandLineParser::processArgs() string invsStr = m_args[g_strModelCheckerInvariants].as(); optional invs = ModelCheckerInvariants::fromString(invsStr); if (!invs) - { - serr() << "Invalid option for --" << g_strModelCheckerInvariants << ": " << invsStr << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid option for --" + g_strModelCheckerInvariants + ": " + invsStr); m_options.modelChecker.settings.invariants = *invs; } @@ -1282,10 +1228,7 @@ bool CommandLineParser::processArgs() string solversStr = m_args[g_strModelCheckerSolvers].as(); optional solvers = smtutil::SMTSolverChoice::fromString(solversStr); if (!solvers) - { - serr() << "Invalid option for --" << g_strModelCheckerSolvers << ": " << solversStr << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid option for --" + g_strModelCheckerSolvers + ": " + solversStr); m_options.modelChecker.settings.solvers = *solvers; } @@ -1294,10 +1237,7 @@ bool CommandLineParser::processArgs() string targetsStr = m_args[g_strModelCheckerTargets].as(); optional targets = ModelCheckerTargets::fromString(targetsStr); if (!targets) - { - serr() << "Invalid option for --" << g_strModelCheckerTargets << ": " << targetsStr << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid option for --" + g_strModelCheckerTargets + ": " + targetsStr); m_options.modelChecker.settings.targets = *targets; } @@ -1319,27 +1259,21 @@ bool CommandLineParser::processArgs() m_options.input.errorRecovery = (m_args.count(g_strErrorRecovery) > 0); solAssert(m_options.input.mode == InputMode::Compiler || m_options.input.mode == InputMode::CompilerWithASTImport); - return true; } -bool CommandLineParser::parseCombinedJsonOption() +void CommandLineParser::parseCombinedJsonOption() { if (!m_args.count(g_strCombinedJson)) - return true; + return; set requests; for (string const& item: boost::split(requests, m_args[g_strCombinedJson].as(), boost::is_any_of(","))) if (CombinedJsonRequests::componentMap().count(item) == 0) - { - serr() << "Invalid option to --" << g_strCombinedJson << ": " << item << endl; - return false; - } + solThrow(CommandLineValidationError, "Invalid option to --" + g_strCombinedJson + ": " + item); m_options.compiler.combinedJsonRequests = CombinedJsonRequests{}; for (auto&& [componentName, component]: CombinedJsonRequests::componentMap()) m_options.compiler.combinedJsonRequests.value().*component = (requests.count(componentName) > 0); - - return true; } size_t CommandLineParser::countEnabledOptions(vector const& _optionNames) const diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index a1d13c6907..33a4a24552 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -234,7 +234,7 @@ struct CommandLineOptions }; /// Parses the command-line arguments and produces a filled-out CommandLineOptions structure. -/// Validates provided values and prints error messages in case of errors. +/// Validates provided values and reports errors by throwing @p CommandLineValidationErrors. class CommandLineParser { public: @@ -243,12 +243,9 @@ class CommandLineParser {} /// Parses the command-line arguments and fills out the internal CommandLineOptions structure. - /// Performs validation and prints error messages. - /// @return true if there were no validation errors when parsing options and the - /// CommandLineOptions structure has been fully initialized. false if there were errors - in - /// this case CommandLineOptions may be only partially filled out. May also return false if - /// there is not further processing necessary and the program should just exit. - bool parse(int _argc, char const* const* _argv); + /// @throws CommandLineValidationError if the arguments cannot be properly parsed or are invalid. + /// When an exception is thrown, the @p CommandLineOptions may be only partially filled out. + void parse(int _argc, char const* const* _argv); CommandLineOptions const& options() const { return m_options; } @@ -269,30 +266,29 @@ class CommandLineParser /// Uses boost::program_options to parse the command-line arguments and leaves the result in @a m_args. /// Also handles the arguments that result in information being printed followed by immediate exit. /// @returns false if parsing fails due to syntactical errors or the arguments not matching the description. - bool parseArgs(int _argc, char const* const* _argv); + void parseArgs(int _argc, char const* const* _argv); /// Validates parsed arguments stored in @a m_args and fills out the internal CommandLineOptions /// structure. - /// @return false if there are any validation errors, true otherwise. - bool processArgs(); + /// @throws CommandLineValidationError in case of validation errors. + void processArgs(); /// Parses the value supplied to --combined-json. - /// @return false if there are any validation errors, true otherwise. - bool parseCombinedJsonOption(); + /// @throws CommandLineValidationError in case of validation errors. + void parseCombinedJsonOption(); - /// Parses the names of the input files, remappings for all modes except for Standard JSON. - /// Does not check if files actually exist. - /// @return false if there are any validation errors, true otherwise. - bool parseInputPathsAndRemappings(); + /// Parses the names of the input files, remappings. Does not check if the files actually exist. + /// @throws CommandLineValidationError in case of validation errors. + void parseInputPathsAndRemappings(); /// Tries to read from the file @a _input or interprets @a _input literally if that fails. - /// It then tries to parse the contents and appends to m_options.libraries. - /// @return false if there are any validation errors, true otherwise. - bool parseLibraryOption(std::string const& _input); + /// It then tries to parse the contents and appends to @a m_options.libraries. + /// @throws CommandLineValidationError in case of validation errors. + void parseLibraryOption(std::string const& _input); - bool parseOutputSelection(); + void parseOutputSelection(); - bool checkMutuallyExclusive(std::vector const& _optionNames); + void checkMutuallyExclusive(std::vector const& _optionNames); size_t countEnabledOptions(std::vector const& _optionNames) const; static std::string joinOptionNames(std::vector const& _optionNames, std::string _separator = ", "); diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 23ea1efb16..385ab279aa 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -19,6 +19,7 @@ /// Unit tests for solc/CommandLineParser.h #include +#include #include @@ -46,17 +47,14 @@ using namespace solidity::yul; namespace { -optional parseCommandLine(vector const& _commandLine, ostream& _stderr) +CommandLineOptions parseCommandLine(vector const& _commandLine) { vector argv = test::makeArgv(_commandLine); - CommandLineParser cliParser(_stderr); - bool success = cliParser.parse(static_cast(_commandLine.size()), argv.data()); - - if (!success) - return nullopt; - else - return cliParser.options(); + stringstream serr; + CommandLineParser cliParser(serr); + cliParser.parse(static_cast(_commandLine.size()), argv.data()); + return cliParser.options(); } } // namespace @@ -75,12 +73,9 @@ BOOST_AUTO_TEST_CASE(no_options) expectedOptions.modelChecker.initialize = true; expectedOptions.modelChecker.settings = {}; - stringstream serr; - optional parsedOptions = parseCommandLine(commandLine, serr); + CommandLineOptions parsedOptions = parseCommandLine(commandLine); - BOOST_TEST(serr.str() == ""); - BOOST_REQUIRE(parsedOptions.has_value()); - BOOST_TEST(parsedOptions.value() == expectedOptions); + BOOST_TEST(parsedOptions == expectedOptions); } BOOST_AUTO_TEST_CASE(help_license_version) @@ -93,15 +88,12 @@ BOOST_AUTO_TEST_CASE(help_license_version) for (auto const& [option, expectedMode]: expectedModePerOption) { - stringstream serr; - optional parsedOptions = parseCommandLine({"solc", option}, serr); + CommandLineOptions parsedOptions = parseCommandLine({"solc", option}); CommandLineOptions expectedOptions; expectedOptions.input.mode = expectedMode; - BOOST_TEST(serr.str() == ""); - BOOST_REQUIRE(parsedOptions.has_value()); - BOOST_TEST(parsedOptions.value() == expectedOptions); + BOOST_TEST(parsedOptions == expectedOptions); } } @@ -226,12 +218,9 @@ BOOST_AUTO_TEST_CASE(cli_mode_options) 5, }; - stringstream serr; - optional parsedOptions = parseCommandLine(commandLine, serr); + CommandLineOptions parsedOptions = parseCommandLine(commandLine); - BOOST_TEST(serr.str() == ""); - BOOST_REQUIRE(parsedOptions.has_value()); - BOOST_TEST(parsedOptions.value() == expectedOptions); + BOOST_TEST(parsedOptions == expectedOptions); } } @@ -352,12 +341,9 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) expectedOptions.optimizer.expectedExecutionsPerDeployment = 1000; } - stringstream serr; - optional parsedOptions = parseCommandLine(commandLine, serr); + CommandLineOptions parsedOptions = parseCommandLine(commandLine); - BOOST_TEST(serr.str() == "Warning: Yul is still experimental. Please use the output with care.\n"); - BOOST_REQUIRE(parsedOptions.has_value()); - BOOST_TEST(parsedOptions.value() == expectedOptions); + BOOST_TEST(parsedOptions == expectedOptions); } } @@ -420,12 +406,9 @@ BOOST_AUTO_TEST_CASE(standard_json_mode_options) expectedOptions.compiler.combinedJsonRequests->abi = true; expectedOptions.compiler.combinedJsonRequests->binary = true; - stringstream serr; - optional parsedOptions = parseCommandLine(commandLine, serr); + CommandLineOptions parsedOptions = parseCommandLine(commandLine); - BOOST_TEST(serr.str() == ""); - BOOST_REQUIRE(parsedOptions.has_value()); - BOOST_TEST(parsedOptions.value() == expectedOptions); + BOOST_TEST(parsedOptions == expectedOptions); } BOOST_AUTO_TEST_CASE(invalid_options_input_modes_combinations) @@ -441,10 +424,11 @@ BOOST_AUTO_TEST_CASE(invalid_options_input_modes_combinations) { stringstream serr; vector commandLine = {"solc", optionName, "file", inputMode}; - optional parsedOptions = parseCommandLine(commandLine, serr); - BOOST_TEST(serr.str() == "The following options are not supported in the current input mode: " + optionName + "\n"); - BOOST_REQUIRE(!parsedOptions.has_value()); + string expectedMessage = "The following options are not supported in the current input mode: " + optionName; + auto hasCorrectMessage = [&](CommandLineValidationError const& _exception) { return _exception.what() == expectedMessage; }; + + BOOST_CHECK_EXCEPTION(parseCommandLine(commandLine), CommandLineValidationError, hasCorrectMessage); } } From 16f62ed43e58a889ac9b51dc93b776712402fcd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 11 Oct 2021 14:20:56 +0200 Subject: [PATCH 0116/1748] Move the Yul experimental warning from CommandLineParser to CommandLineInterface and remove stderr from the parser --- solc/CommandLineInterface.cpp | 5 +++-- solc/CommandLineParser.cpp | 12 ------------ solc/CommandLineParser.h | 14 -------------- test/solc/CommandLineParser.cpp | 3 +-- 4 files changed, 4 insertions(+), 30 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 78e60ad0cb..2c7c274f58 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -583,7 +583,7 @@ void CommandLineInterface::createJson(string const& _fileName, string const& _js bool CommandLineInterface::parseArguments(int _argc, char const* const* _argv) { - CommandLineParser parser(serr(/* _markAsUsed */ false)); + CommandLineParser parser; if (isatty(fileno(stdin)) && _argc == 1) { @@ -604,7 +604,6 @@ bool CommandLineInterface::parseArguments(int _argc, char const* const* _argv) return false; } - m_hasOutput = m_hasOutput || parser.hasOutput(); m_options = parser.options(); return true; @@ -1003,6 +1002,8 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul: { solAssert(m_options.input.mode == InputMode::Assembler, ""); + serr() << "Warning: Yul is still experimental. Please use the output with care." << endl; + bool successful = true; map assemblyStacks; for (auto const& src: m_fileReader.sourceCodes()) diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index cdd74a2172..87348686c6 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -38,14 +38,6 @@ namespace po = boost::program_options; namespace solidity::frontend { -ostream& CommandLineParser::serr() -{ - m_hasOutput = true; - return m_serr; -} - -#define cerr - static string const g_strAllowPaths = "allow-paths"; static string const g_strBasePath = "base-path"; static string const g_strIncludePath = "include-path"; @@ -278,8 +270,6 @@ OptimiserSettings CommandLineOptions::optimiserSettings() const void CommandLineParser::parse(int _argc, char const* const* _argv) { - m_hasOutput = false; - parseArgs(_argc, _argv); processArgs(); } @@ -1167,8 +1157,6 @@ void CommandLineParser::processArgs() "The selected input language is not directly supported when targeting the Ewasm machine " "and automatic translation is not available." ); - - serr() << "Warning: Yul is still experimental. Please use the output with care." << endl; return; } else if (countEnabledOptions({g_strYulDialect, g_strMachine}) >= 1) diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index 33a4a24552..c1a95a11f9 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -238,10 +238,6 @@ struct CommandLineOptions class CommandLineParser { public: - explicit CommandLineParser(std::ostream& _serr): - m_serr(_serr) - {} - /// Parses the command-line arguments and fills out the internal CommandLineOptions structure. /// @throws CommandLineValidationError if the arguments cannot be properly parsed or are invalid. /// When an exception is thrown, the @p CommandLineOptions may be only partially filled out. @@ -249,9 +245,6 @@ class CommandLineParser CommandLineOptions const& options() const { return m_options; } - /// Returns true if the parser has written anything to any of its output streams. - bool hasOutput() const { return m_hasOutput; } - static void printHelp(std::ostream& _out) { _out << optionsDescription(); } private: @@ -292,13 +285,6 @@ class CommandLineParser size_t countEnabledOptions(std::vector const& _optionNames) const; static std::string joinOptionNames(std::vector const& _optionNames, std::string _separator = ", "); - /// Returns the stream that should receive error output. Sets m_hasOutput to true if the - /// stream has ever been used. - std::ostream& serr(); - - std::ostream& m_serr; - bool m_hasOutput = false; - CommandLineOptions m_options; /// Map of command-line arguments produced by boost::program_options. diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 385ab279aa..c2eab23557 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -51,8 +51,7 @@ CommandLineOptions parseCommandLine(vector const& _commandLine) { vector argv = test::makeArgv(_commandLine); - stringstream serr; - CommandLineParser cliParser(serr); + CommandLineParser cliParser; cliParser.parse(static_cast(_commandLine.size()), argv.data()); return cliParser.options(); } From e829bcd93370d7caddae9458e75bdea3e4fec9ab Mon Sep 17 00:00:00 2001 From: neel iyer <33139997+spiyer99@users.noreply.github.com> Date: Sun, 15 Aug 2021 11:14:38 +1000 Subject: [PATCH 0117/1748] CommandLineInterface: Replace code that prints to serr() and returns false with CommandLineValidationError exception --- solc/CommandLineInterface.cpp | 77 ++++++++++++++++------------------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 2c7c274f58..5aeaa02c26 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -420,16 +420,10 @@ bool CommandLineInterface::readInputFiles() if (m_fileReader.basePath() != "") { if (!boost::filesystem::exists(m_fileReader.basePath())) - { - serr() << "Base path does not exist: " << m_fileReader.basePath() << endl; - return false; - } + solThrow(CommandLineValidationError, "Base path does not exist: \"" + m_fileReader.basePath().string() + '"'); if (!boost::filesystem::is_directory(m_fileReader.basePath())) - { - serr() << "Base path is not a directory: " << m_fileReader.basePath() << endl; - return false; - } + solThrow(CommandLineValidationError, "Base path is not a directory: \"" + m_fileReader.basePath().string() + '"'); } for (boost::filesystem::path const& includePath: m_options.input.includePaths) @@ -444,16 +438,18 @@ bool CommandLineInterface::readInputFiles() { auto pathToQuotedString = [](boost::filesystem::path const& _path){ return "\"" + _path.string() + "\""; }; - serr() << "Source unit name collision detected. "; - serr() << "The specified values of base path and/or include paths would result in multiple "; - serr() << "input files being assigned the same source unit name:" << endl; + string message = + "Source unit name collision detected. " + "The specified values of base path and/or include paths would result in multiple " + "input files being assigned the same source unit name:\n"; + for (auto const& [sourceUnitName, normalizedInputPaths]: collisions) { - serr() << sourceUnitName << " matches: "; - serr() << joinHumanReadable(normalizedInputPaths | ranges::views::transform(pathToQuotedString)) << endl; + message += sourceUnitName + " matches: "; + message += joinHumanReadable(normalizedInputPaths | ranges::views::transform(pathToQuotedString)) + "\n"; } - return false; + solThrow(CommandLineValidationError, message); } for (boost::filesystem::path const& infile: m_options.input.paths) @@ -461,10 +457,7 @@ bool CommandLineInterface::readInputFiles() if (!boost::filesystem::exists(infile)) { if (!m_options.input.ignoreMissingFiles) - { - serr() << infile << " is not found." << endl; - return false; - } + solThrow(CommandLineValidationError, '"' + infile.string() + "\" is not found."); else serr() << infile << " is not found. Skipping." << endl; @@ -474,10 +467,7 @@ bool CommandLineInterface::readInputFiles() if (!boost::filesystem::is_regular_file(infile)) { if (!m_options.input.ignoreMissingFiles) - { - serr() << infile << " is not a valid file." << endl; - return false; - } + solThrow(CommandLineValidationError, '"' + infile.string() + "\" is not a valid file."); else serr() << infile << " is not a valid file. Skipping." << endl; @@ -510,10 +500,7 @@ bool CommandLineInterface::readInputFiles() } if (m_fileReader.sourceCodes().empty() && !m_standardJsonInput.has_value()) - { - serr() << "All specified input files either do not exist or are not regular files." << endl; - return false; - } + solThrow(CommandLineValidationError, "All specified input files either do not exist or are not regular files."); return true; } @@ -647,7 +634,8 @@ bool CommandLineInterface::processInput() outputCompilationResults(); } - return !m_outputFailed; + if (m_outputFailed) + solThrow(CommandLineOutputError, "Failed to write all output files to disk."); } void CommandLineInterface::printVersion() @@ -726,8 +714,7 @@ bool CommandLineInterface::compile() } catch (Exception const& _exc) { - serr() << string("Failed to import AST: ") << _exc.what() << endl; - return false; + solThrow(CommandLineExecutionError, "Failed to import AST: "s + _exc.what()); } } else @@ -744,26 +731,28 @@ bool CommandLineInterface::compile() formatter.printErrorInformation(*error); } - if (!successful) - return m_options.input.errorRecovery; + if (!successful && !m_options.input.errorRecovery) + solThrow(CommandLineExecutionError, ""); } catch (CompilerError const& _exception) { m_hasOutput = true; formatter.printExceptionInformation(_exception, "Compiler error"); - return false; + solThrow(CommandLineExecutionError, ""); } catch (Error const& _error) { if (_error.type() == Error::Type::DocstringParsingError) - serr() << "Documentation parsing error: " << *boost::get_error_info(_error) << endl; + { + serr() << *boost::get_error_info(_error); + solThrow(CommandLineExecutionError, "Documentation parsing failed."); + } else { m_hasOutput = true; formatter.printExceptionInformation(_error, _error.typeName()); + solThrow(CommandLineExecutionError, ""); } - - return false; } return true; @@ -933,11 +922,11 @@ bool CommandLineInterface::link() *(it + placeholderSize - 2) != '_' || *(it + placeholderSize - 1) != '_' ) - { - serr() << "Error in binary object file " << src.first << " at position " << (it - src.second.begin()) << endl; - serr() << '"' << string(it, it + min(placeholderSize, static_cast(end - it))) << "\" is not a valid link reference." << endl; - return false; - } + solThrow( + CommandLineExecutionError, + "Error in binary object file " + src.first + " at position " + to_string(it - src.second.begin()) + "\n" + + '"' + string(it, it + min(placeholderSize, static_cast(end - it))) + "\" is not a valid link reference." + ); string foundPlaceholder(it, it + placeholderSize); if (librariesReplacements.count(foundPlaceholder)) @@ -973,9 +962,8 @@ void CommandLineInterface::writeLinkedFiles() outFile << src.second; if (!outFile) { - serr() << "Could not write to file " << src.first << ". Aborting." << endl; m_outputFailed = true; - return; + solThrow(CommandLineOutputError, "Could not write to file " + src.first + ". Aborting."); } } sout() << "Linking completed." << endl; @@ -1041,7 +1029,10 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul: } if (!successful) - return false; + { + solAssert(m_hasOutput); + solThrow(CommandLineExecutionError, ""); + } for (auto const& src: m_fileReader.sourceCodes()) { From c8380c25bb4123d174f6c550c8b163fbcde8f36f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 12 Oct 2021 14:16:29 +0200 Subject: [PATCH 0118/1748] CommandLineInterface: Update control flow to accommodate the new way of reporting errors --- solc/CommandLineInterface.cpp | 70 +++---- solc/CommandLineInterface.h | 32 +++- solc/main.cpp | 7 +- test/solc/CommandLineInterface.cpp | 191 +++++++++---------- test/solc/CommandLineInterfaceAllowPaths.cpp | 6 +- test/solc/Common.cpp | 28 ++- test/solc/Common.h | 20 +- 7 files changed, 196 insertions(+), 158 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 5aeaa02c26..08b45c6ee0 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -404,7 +404,7 @@ void CommandLineInterface::handleGasEstimation(string const& _contract) } } -bool CommandLineInterface::readInputFiles() +void CommandLineInterface::readInputFiles() { solAssert(!m_standardJsonInput.has_value(), ""); @@ -413,7 +413,7 @@ bool CommandLineInterface::readInputFiles() m_options.input.mode == InputMode::License || m_options.input.mode == InputMode::Version ) - return true; + return; m_fileReader.setBasePath(m_options.input.basePath); @@ -501,8 +501,6 @@ bool CommandLineInterface::readInputFiles() if (m_fileReader.sourceCodes().empty() && !m_standardJsonInput.has_value()) solThrow(CommandLineValidationError, "All specified input files either do not exist or are not regular files."); - - return true; } map CommandLineInterface::parseAstFromInput() @@ -568,6 +566,30 @@ void CommandLineInterface::createJson(string const& _fileName, string const& _js createFile(boost::filesystem::basename(_fileName) + string(".json"), _json); } +bool CommandLineInterface::run(int _argc, char const* const* _argv) +{ + try + { + if (!parseArguments(_argc, _argv)) + return false; + + readInputFiles(); + processInput(); + return true; + } + catch (CommandLineError const& _exception) + { + m_hasOutput = true; + + // There might be no message in the exception itself if the error output is bulky and has + // already been printed to stderr (this happens e.g. for compiler errors). + if (_exception.what() != ""s) + serr() << _exception.what() << endl; + + return false; + } +} + bool CommandLineInterface::parseArguments(int _argc, char const* const* _argv) { CommandLineParser parser; @@ -581,22 +603,13 @@ bool CommandLineInterface::parseArguments(int _argc, char const* const* _argv) return false; } - try - { - parser.parse(_argc, _argv); - } - catch (CommandLineValidationError const& _exception) - { - serr() << _exception.what() << endl; - return false; - } - + parser.parse(_argc, _argv); m_options = parser.options(); return true; } -bool CommandLineInterface::processInput() +void CommandLineInterface::processInput() { switch (m_options.input.mode) { @@ -619,18 +632,15 @@ bool CommandLineInterface::processInput() break; } case InputMode::Assembler: - if (!assemble(m_options.assembly.inputLanguage, m_options.assembly.targetMachine)) - return false; + assemble(m_options.assembly.inputLanguage, m_options.assembly.targetMachine); break; case InputMode::Linker: - if (!link()) - return false; + link(); writeLinkedFiles(); break; case InputMode::Compiler: case InputMode::CompilerWithASTImport: - if (!compile()) - return false; + compile(); outputCompilationResults(); } @@ -651,7 +661,7 @@ void CommandLineInterface::printLicense() sout() << licenseText << endl; } -bool CommandLineInterface::compile() +void CommandLineInterface::compile() { solAssert(m_options.input.mode == InputMode::Compiler || m_options.input.mode == InputMode::CompilerWithASTImport, ""); @@ -714,6 +724,8 @@ bool CommandLineInterface::compile() } catch (Exception const& _exc) { + // FIXME: AST import is missing proper validations. This hack catches failing + // assertions and presents them as if they were compiler errors. solThrow(CommandLineExecutionError, "Failed to import AST: "s + _exc.what()); } } @@ -754,8 +766,6 @@ bool CommandLineInterface::compile() solThrow(CommandLineExecutionError, ""); } } - - return true; } void CommandLineInterface::handleCombinedJSON() @@ -884,7 +894,7 @@ void CommandLineInterface::handleAst() } } -bool CommandLineInterface::link() +void CommandLineInterface::link() { solAssert(m_options.input.mode == InputMode::Linker, ""); @@ -945,8 +955,6 @@ bool CommandLineInterface::link() src.second.resize(src.second.size() - 1); } m_fileReader.setSources(move(sourceCodes)); - - return true; } void CommandLineInterface::writeLinkedFiles() @@ -986,7 +994,7 @@ string CommandLineInterface::objectWithLinkRefsHex(evmasm::LinkerObject const& _ return out; } -bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul::AssemblyStack::Machine _targetMachine) +void CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul::AssemblyStack::Machine _targetMachine) { solAssert(m_options.input.mode == InputMode::Assembler, ""); @@ -1090,8 +1098,6 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul: serr() << "No text representation found." << endl; } } - - return true; } void CommandLineInterface::outputCompilationResults() @@ -1128,13 +1134,9 @@ void CommandLineInterface::outputCompilationResults() ret = m_compiler->assemblyString(contract, m_fileReader.sourceCodes()); if (!m_options.output.dir.empty()) - { createFile(m_compiler->filesystemFriendlyName(contract) + (m_options.compiler.outputs.asmJson ? "_evm.json" : ".evm"), ret); - } else - { sout() << "EVM assembly:" << endl << ret << endl; - } } if (m_options.compiler.estimateGas) diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index ee50574682..fc584001f7 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -51,12 +51,28 @@ class CommandLineInterface m_options(_options) {} - /// Parse command line arguments and return false if we should not continue + /// Parses command-line arguments, executes the requested operation and handles validation and + /// execution errors. + /// @returns false if it catches a @p CommandLineValidationError or if the application is + /// expected to exit with a non-zero exit code despite there being no error. + bool run(int _argc, char const* const* _argv); + + /// Parses command line arguments and stores the result in @p m_options. + /// @throws CommandLineValidationError if command-line arguments are invalid. + /// @returns false if the application is expected to exit with a non-zero exit code despite + /// there being no error. bool parseArguments(int _argc, char const* const* _argv); - /// Read the content of all input files and initialize the file reader. - bool readInputFiles(); - /// Parse the files, create source code objects, print the output. - bool processInput(); + + /// Reads the content of all input files and initializes the file reader. + /// @throws CommandLineValidationError if it fails to read the input files (invalid paths, + /// non-existent files, not enough or too many input files, etc.). + void readInputFiles(); + + /// Executes the requested operation (compilation, assembling, standard JSON, etc.) and prints + /// results to the terminal. + /// @throws CommandLineExecutionError if execution fails due to errors in the input files. + /// @throws CommandLineOutputError if creating output files or writing to them fails. + void processInput(); CommandLineOptions const& options() const { return m_options; } FileReader const& fileReader() const { return m_fileReader; } @@ -65,15 +81,15 @@ class CommandLineInterface private: void printVersion(); void printLicense(); - bool compile(); - bool link(); + void compile(); + void link(); void writeLinkedFiles(); /// @returns the ``// -> name`` hint for library placeholders. static std::string libraryPlaceholderHint(std::string const& _libraryName); /// @returns the full object with library placeholder hints in hex. static std::string objectWithLinkRefsHex(evmasm::LinkerObject const& _obj); - bool assemble(yul::AssemblyStack::Language _language, yul::AssemblyStack::Machine _targetMachine); + void assemble(yul::AssemblyStack::Language _language, yul::AssemblyStack::Machine _targetMachine); void outputCompilationResults(); diff --git a/solc/main.cpp b/solc/main.cpp index 874ee13ca8..ce69d20a79 100644 --- a/solc/main.cpp +++ b/solc/main.cpp @@ -62,12 +62,7 @@ int main(int argc, char** argv) { setDefaultOrCLocale(); solidity::frontend::CommandLineInterface cli(cin, cout, cerr); - bool success = - cli.parseArguments(argc, argv) && - cli.readInputFiles() && - cli.processInput(); - - return success ? 0 : 1; + return cli.run(argc, argv) ? 0 : 1; } catch (smtutil::SMTLogicError const& _exception) { diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 0269ec462f..dbffc47889 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -19,6 +19,7 @@ /// Unit tests for solc/CommandLineInterface.h #include +#include #include @@ -114,7 +115,7 @@ BOOST_AUTO_TEST_SUITE(CommandLineInterfaceTest) BOOST_AUTO_TEST_CASE(help) { - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--help"}, "", /* _processInput */ true); + OptionsReaderAndMessages result = runCLI({"solc", "--help"}, ""); BOOST_TEST(result.success); BOOST_TEST(boost::starts_with(result.stdoutContent, "solc, the Solidity commandline compiler.")); @@ -124,7 +125,7 @@ BOOST_AUTO_TEST_CASE(help) BOOST_AUTO_TEST_CASE(license) { - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--license"}, "", /* _processInput */ true); + OptionsReaderAndMessages result = runCLI({"solc", "--license"}, ""); BOOST_TEST(result.success); BOOST_TEST(boost::starts_with(result.stdoutContent, "Most of the code is licensed under GPLv3")); @@ -134,7 +135,7 @@ BOOST_AUTO_TEST_CASE(license) BOOST_AUTO_TEST_CASE(version) { - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", "--version"}, "", /* _processInput */ true); + OptionsReaderAndMessages result = runCLI({"solc", "--version"}, ""); BOOST_TEST(result.success); BOOST_TEST(boost::ends_with(result.stdoutContent, "Version: " + solidity::frontend::VersionString + "\n")); @@ -158,17 +159,16 @@ BOOST_AUTO_TEST_CASE(multiple_input_modes) string expectedMessage = "The following options are mutually exclusive: " "--help, --license, --version, --standard-json, --link, --assemble, --strict-assembly, --yul, --import-ast. " - "Select at most one.\n"; + "Select at most one."; for (string const& mode1: inputModeOptions) for (string const& mode2: inputModeOptions) if (mode1 != mode2) - { - vector commandLine = {"solc", mode1, mode2}; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles(commandLine); - BOOST_TEST(!result.success); - BOOST_TEST(result.stderrContent == expectedMessage); - } + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles({"solc", mode1, mode2}), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); } BOOST_AUTO_TEST_CASE(cli_input) @@ -253,7 +253,7 @@ BOOST_AUTO_TEST_CASE(cli_ignore_missing_no_files_exist) "\"" + (tempDir.path() / "input2.sol").string() + "\" is not found. Skipping.\n" "All specified input files either do not exist or are not regular files.\n"; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({ + OptionsReaderAndMessages result = runCLI({ "solc", (tempDir.path() / "input1.sol").string(), (tempDir.path() / "input2.sol").string(), @@ -267,11 +267,13 @@ BOOST_AUTO_TEST_CASE(cli_not_a_file) { TemporaryDirectory tempDir(TEST_CASE_NAME); - string expectedMessage = "\"" + tempDir.path().string() + "\" is not a valid file.\n"; + string expectedMessage = "\"" + tempDir.path().string() + "\" is not a valid file."; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({"solc", tempDir.path().string()}); - BOOST_TEST(!result.success); - BOOST_TEST(result.stderrContent == expectedMessage); + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles({"solc", tempDir.path().string()}), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); } BOOST_AUTO_TEST_CASE(standard_json_base_path) @@ -336,24 +338,26 @@ BOOST_AUTO_TEST_CASE(standard_json_two_input_files) { string expectedMessage = "Too many input files for --standard-json.\n" - "Please either specify a single file name or provide its content on standard input.\n"; + "Please either specify a single file name or provide its content on standard input."; - vector commandLine = {"solc", "--standard-json", "input1.json", "input2.json"}; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles(commandLine); - BOOST_TEST(!result.success); - BOOST_TEST(result.stderrContent == expectedMessage); + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles({"solc", "--standard-json", "input1.json", "input2.json"}), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); } BOOST_AUTO_TEST_CASE(standard_json_one_input_file_and_stdin) { string expectedMessage = "Too many input files for --standard-json.\n" - "Please either specify a single file name or provide its content on standard input.\n"; + "Please either specify a single file name or provide its content on standard input."; - vector commandLine = {"solc", "--standard-json", "input1.json", "-"}; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles(commandLine); - BOOST_TEST(!result.success); - BOOST_TEST(result.stderrContent == expectedMessage); + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles({"solc", "--standard-json", "input1.json", "-"}), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); } BOOST_AUTO_TEST_CASE(standard_json_ignore_missing) @@ -362,29 +366,31 @@ BOOST_AUTO_TEST_CASE(standard_json_ignore_missing) // This option is pretty much useless Standard JSON mode. string expectedMessage = - "\"" + (tempDir.path() / "input.json").string() + "\" is not found. Skipping.\n" - "All specified input files either do not exist or are not regular files.\n"; + "All specified input files either do not exist or are not regular files."; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({ - "solc", - "--standard-json", - (tempDir.path() / "input.json").string(), - "--ignore-missing", - }); - BOOST_TEST(!result.success); - BOOST_TEST(result.stderrContent == expectedMessage); + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles({ + "solc", + "--standard-json", + (tempDir.path() / "input.json").string(), + "--ignore-missing", + }), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); } BOOST_AUTO_TEST_CASE(standard_json_remapping) { string expectedMessage = "Import remappings are not accepted on the command line in Standard JSON mode.\n" - "Please put them under 'settings.remappings' in the JSON input.\n"; + "Please put them under 'settings.remappings' in the JSON input."; - vector commandLine = {"solc", "--standard-json", "a=b"}; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles(commandLine); - BOOST_TEST(!result.success); - BOOST_TEST(result.stderrContent == expectedMessage); + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles({"solc", "--standard-json", "a=b"}), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); } BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_no_base_path) @@ -997,11 +1003,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths) canonicalWorkDir / "lib", }; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles( - commandLine, - "", - true /* _processInput */ - ); + OptionsReaderAndMessages result = runCLI(commandLine, ""); BOOST_TEST(result.stderrContent == ""); BOOST_TEST(result.stdoutContent == ""); @@ -1087,11 +1089,7 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths) FileReader::FileSystemPathSet expectedAllowedDirectories = {}; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles( - commandLine, - standardJsonInput, - true /* _processInput */ - ); + OptionsReaderAndMessages result = runCLI(commandLine, standardJsonInput); Json::Value parsedStdout; string jsonParsingErrors; @@ -1119,18 +1117,19 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_empty_path) TemporaryWorkingDirectory tempWorkDir(tempDir); createFilesWithParentDirs({tempDir.path() / "base/main.sol"}); - string expectedMessage = "Empty values are not allowed in --include-path.\n"; + string expectedMessage = "Empty values are not allowed in --include-path."; - vector commandLine = { - "solc", - "--base-path=base/", - "--include-path", "include/", - "--include-path", "", - "base/main.sol", - }; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles(commandLine); - BOOST_TEST(!result.success); - BOOST_TEST(result.stderrContent == expectedMessage); + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles({ + "solc", + "--base-path=base/", + "--include-path", "include/", + "--include-path", "", + "base/main.sol", + }), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); } BOOST_AUTO_TEST_CASE(cli_include_paths_without_base_path) @@ -1139,12 +1138,13 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_without_base_path) TemporaryWorkingDirectory tempWorkDir(tempDir); createFilesWithParentDirs({tempDir.path() / "contract.sol"}); - string expectedMessage = "--include-path option requires a non-empty base path.\n"; + string expectedMessage = "--include-path option requires a non-empty base path."; - vector commandLine = {"solc", "--include-path", "include/", "contract.sol"}; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles(commandLine); - BOOST_TEST(!result.success); - BOOST_TEST(result.stderrContent == expectedMessage); + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles({"solc", "--include-path", "include/", "contract.sol"}), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); } BOOST_AUTO_TEST_CASE(cli_include_paths_should_detect_source_unit_name_collisions) @@ -1173,35 +1173,37 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_should_detect_source_unit_name_collisions { // import "contract1.sol" and import "contract2.sol" would be ambiguous: - vector commandLine = { - "solc", - "--base-path=dir1/", - "--include-path=dir2/", - "dir1/contract1.sol", - "dir2/contract1.sol", - "dir1/contract2.sol", - "dir2/contract2.sol", - }; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles(commandLine); - BOOST_TEST(result.stderrContent == expectedMessage); - BOOST_REQUIRE(!result.success); + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles({ + "solc", + "--base-path=dir1/", + "--include-path=dir2/", + "dir1/contract1.sol", + "dir2/contract1.sol", + "dir1/contract2.sol", + "dir2/contract2.sol", + }), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); } { // import "contract1.sol" and import "contract2.sol" would be ambiguous: - vector commandLine = { - "solc", - "--base-path=dir3/", - "--include-path=dir1/", - "--include-path=dir2/", - "dir1/contract1.sol", - "dir2/contract1.sol", - "dir1/contract2.sol", - "dir2/contract2.sol", - }; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles(commandLine); - BOOST_TEST(result.stderrContent == expectedMessage); - BOOST_REQUIRE(!result.success); + BOOST_CHECK_EXCEPTION( + parseCommandLineAndReadInputFiles({ + "solc", + "--base-path=dir3/", + "--include-path=dir1/", + "--include-path=dir2/", + "dir1/contract1.sol", + "dir2/contract1.sol", + "dir1/contract2.sol", + "dir2/contract2.sol", + }), + CommandLineValidationError, + [&](auto const& _exception) { BOOST_TEST(_exception.what() == expectedMessage); return true; } + ); } { @@ -1316,12 +1318,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_ambiguous_import) "3 | import \"contract.sol\";\n" " | ^^^^^^^^^^^^^^^^^^^^^^\n\n"; - OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles( - commandLine, - mainContractSource, - true /* _processInput */ - ); - + OptionsReaderAndMessages result = runCLI(commandLine, mainContractSource); BOOST_TEST(result.stderrContent == expectedMessage); BOOST_REQUIRE(!result.success); } diff --git a/test/solc/CommandLineInterfaceAllowPaths.cpp b/test/solc/CommandLineInterfaceAllowPaths.cpp index a15199618a..77f727014f 100644 --- a/test/solc/CommandLineInterfaceAllowPaths.cpp +++ b/test/solc/CommandLineInterfaceAllowPaths.cpp @@ -95,11 +95,7 @@ ImportCheck checkImport( "pragma solidity >=0.0;\n" + _import + ";"; - test::OptionsReaderAndMessages cliResult = test::parseCommandLineAndReadInputFiles( - commandLine, - standardInputContent, - true /* processInput */ - ); + test::OptionsReaderAndMessages cliResult = test::runCLI(commandLine, standardInputContent); if (cliResult.success) return ImportCheck::OK(); diff --git a/test/solc/Common.cpp b/test/solc/Common.cpp index 8e40c1af63..ead9b798da 100644 --- a/test/solc/Common.cpp +++ b/test/solc/Common.cpp @@ -41,18 +41,34 @@ vector test::makeArgv(vector const& _commandLine) test::OptionsReaderAndMessages test::parseCommandLineAndReadInputFiles( vector const& _commandLine, - string const& _standardInputContent, - bool _processInput + string const& _standardInputContent ) { vector argv = makeArgv(_commandLine); stringstream sin(_standardInputContent), sout, serr; CommandLineInterface cli(sin, sout, serr); bool success = cli.parseArguments(static_cast(_commandLine.size()), argv.data()); - if (success) - success = cli.readInputFiles(); - if (success && _processInput) - success = cli.processInput(); + cli.readInputFiles(); + + return { + success, + cli.options(), + cli.fileReader(), + cli.standardJsonInput(), + sout.str(), + stripPreReleaseWarning(serr.str()), + }; +} + +test::OptionsReaderAndMessages test::runCLI( + vector const& _commandLine, + string const& _standardInputContent +) +{ + vector argv = makeArgv(_commandLine); + stringstream sin(_standardInputContent), sout, serr; + CommandLineInterface cli(sin, sout, serr); + bool success = cli.run(static_cast(_commandLine.size()), argv.data()); return { success, diff --git a/test/solc/Common.h b/test/solc/Common.h index 958d63054d..3575bea74e 100644 --- a/test/solc/Common.h +++ b/test/solc/Common.h @@ -44,10 +44,26 @@ struct OptionsReaderAndMessages std::vector makeArgv(std::vector const& _commandLine); +/// Runs only command-line parsing, without compilation, assembling or any other input processing. +/// Lets through any @a CommandLineErrors throw by the CLI. +/// Note: This uses the @a CommandLineInterface class and does not actually spawn a new process. +/// @param _commandLine Arguments in the form of strings that would be specified on the command-line. +/// You must specify the program name as the first item. +/// @param _standardInputContent Content that the CLI will be able to read from its standard input. OptionsReaderAndMessages parseCommandLineAndReadInputFiles( std::vector const& _commandLine, - std::string const& _standardInputContent = "", - bool _processInput = false + std::string const& _standardInputContent = "" +); + +/// Runs all stages of command-line interface processing, including error handling. +/// Never throws @a CommandLineError - validation errors are included in the returned stderr content. +/// Note: This uses the @a CommandLineInterface class and does not actually spawn a new process. +/// @param _commandLine Arguments in the form of strings that would be specified on the command-line. +/// You must specify the program name as the first item. +/// @param _standardInputContent Content that the CLI will be able to read from its standard input. +OptionsReaderAndMessages runCLI( + std::vector const& _commandLine, + std::string const& _standardInputContent = "" ); std::string stripPreReleaseWarning(std::string const& _stderrContent); From f50aec9334608a54c345801df1f2230284d12149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 13 Oct 2021 12:55:49 +0200 Subject: [PATCH 0119/1748] CommandLineInterface: Report an error immediately when writing to disk fails --- solc/CommandLineInterface.cpp | 19 +++---------------- solc/CommandLineInterface.h | 1 - 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 08b45c6ee0..4610741020 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -546,19 +546,12 @@ void CommandLineInterface::createFile(string const& _fileName, string const& _da string pathName = (m_options.output.dir / _fileName).string(); if (fs::exists(pathName) && !m_options.output.overwriteFiles) - { - serr() << "Refusing to overwrite existing file \"" << pathName << "\" (use --overwrite to force)." << endl; - m_outputFailed = true; - return; - } + solThrow(CommandLineOutputError, "Refusing to overwrite existing file \"" + pathName + "\" (use --overwrite to force)."); + ofstream outFile(pathName); outFile << _data; if (!outFile) - { - serr() << "Could not write to file \"" << pathName << "\"." << endl; - m_outputFailed = true; - return; - } + solThrow(CommandLineOutputError, "Could not write to file \"" + pathName + "\"."); } void CommandLineInterface::createJson(string const& _fileName, string const& _json) @@ -643,9 +636,6 @@ void CommandLineInterface::processInput() compile(); outputCompilationResults(); } - - if (m_outputFailed) - solThrow(CommandLineOutputError, "Failed to write all output files to disk."); } void CommandLineInterface::printVersion() @@ -969,10 +959,7 @@ void CommandLineInterface::writeLinkedFiles() ofstream outFile(src.first); outFile << src.second; if (!outFile) - { - m_outputFailed = true; solThrow(CommandLineOutputError, "Could not write to file " + src.first + ". Aborting."); - } } sout() << "Linking completed." << endl; } diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index fc584001f7..9d1646e528 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -136,7 +136,6 @@ class CommandLineInterface std::ostream& m_sout; std::ostream& m_serr; bool m_hasOutput = false; - bool m_outputFailed = false; ///< If true, creation or write to some of the output files failed. FileReader m_fileReader; std::optional m_standardJsonInput; std::unique_ptr m_compiler; From 0ec3f523bd22a8196135ea38a7bbab0b8cb1f62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 10 Nov 2021 17:05:23 +0100 Subject: [PATCH 0120/1748] CI: Workaround for $CIRCLE_PULL_REQUEST pointing at random PRs in runs outside of PRs --- .circleci/config.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 72434ea15c..5575c88727 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,7 +44,9 @@ commands: name: "Gitter notification" when: << parameters.condition >> command: | - [[ $CI_PULL_REQUEST == "" ]] || { echo "Running on a PR - notification skipped."; exit 0; } + # FIXME: Checking $CIRCLE_PULL_REQUEST would be better than hard-coding branch names + # but it's broken. CircleCI associates runs on develop/breaking with random old PRs. + [[ $CIRCLE_BRANCH == develop || $CIRCLE_BRANCH == breaking ]] || { echo "Running on a PR or a feature branch - notification skipped."; exit 0; } [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ Nightly job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." [[ "<< parameters.event >>" == "success" ]] && message=" ✅ Nightly job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." From 0d82fe9ca7fcc2fa34a08100c694011261126189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 14 Oct 2021 17:30:13 +0200 Subject: [PATCH 0121/1748] cmdlineTests.sh: Test the equivalence of one and two-stage compilation via IR --- scripts/common.sh | 12 +++++++ test/cmdlineTests.sh | 85 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/scripts/common.sh b/scripts/common.sh index 3e40754a61..fabfb6d72c 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -171,6 +171,18 @@ function msg_on_error fi } +function diff_values +{ + (( $# >= 2 )) || fail "diff_values requires at least 2 arguments." + + local value1="$1" + local value2="$2" + shift + shift + + diff --color=auto --unified=0 <(echo "$value1") <(echo "$value2") "$@" +} + function safe_kill { local PID=${1} diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 2076eb993e..4f9d41384b 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -308,6 +308,61 @@ function test_solc_assembly_output fi } +function test_via_ir_equivalence() +{ + (( $# <= 2 )) || fail "This function accepts at most two arguments." + + if [[ $2 != --optimize ]] && [[ $2 != "" ]] + then + fail "The second argument must be --optimize if present." + fi + + local solidity_code="$1" + local optimize_flag="$2" + + local optimizer_flags=() + [[ $optimize_flag == "" ]] || optimizer_flags+=("$optimize_flag") + + local ir_output + ir_output=$( + echo "$solidity_code" | + msg_on_error --no-stderr "$SOLC" - --ir-optimized --debug-info location "${optimizer_flags[@]}" | + sed '/^Optimized IR:$/d' + ) + + local asm_output_two_stage asm_output_via_ir + asm_output_two_stage=$( + echo "$ir_output" | + msg_on_error --no-stderr "$SOLC" - --strict-assembly --asm "${optimizer_flags[@]}" | + sed '/^======= /d' | + sed '/^Text representation:$/d' + ) + asm_output_via_ir=$( + echo "$solidity_code" | + msg_on_error --no-stderr "$SOLC" - --experimental-via-ir --asm --debug-info location "${optimizer_flags[@]}" | + sed '/^======= /d' | + sed '/^EVM assembly:$/d' + ) + + diff_values "$asm_output_two_stage" "$asm_output_via_ir" --ignore-space-change --ignore-blank-lines + + local bin_output_two_stage bin_output_via_ir + bin_output_two_stage=$( + echo "$ir_output" | + msg_on_error --no-stderr "$SOLC" - --strict-assembly --bin "${optimizer_flags[@]}" | + sed '/^======= /d' | + sed '/^Binary representation:$/d' + ) + bin_output_via_ir=$( + echo "$solidity_code" | + msg_on_error --no-stderr "$SOLC" - --experimental-via-ir --bin "${optimizer_flags[@]}" | + sed '/^======= /d' | + sed '/^Binary:$/d' + ) + + diff_values "$bin_output_two_stage" "$bin_output_via_ir" --ignore-space-change --ignore-blank-lines +} + ## RUN echo "Checking that the bug list is up to date..." @@ -533,6 +588,36 @@ printTask "Testing assemble, yul, strict-assembly and optimize..." test_solc_assembly_output "{ let x := 0 }" "{ { } }" "--strict-assembly --optimize" ) +printTask "Testing the eqivalence of --experimental-via-ir and a two-stage compilation..." +( + printTask " - Smoke test" + test_via_ir_equivalence "contract C {}" + + printTask " - Smoke test (optimized)" + test_via_ir_equivalence "contract C {}" --optimize + + externalContracts=( + deposit_contract.sol + FixedFeeRegistrar.sol + _stringutils/stringutils.sol + ) + requiresOptimizer=( + deposit_contract.sol + FixedFeeRegistrar.sol + ) + + for contractFile in "${externalContracts[@]}" + do + if ! [[ "${requiresOptimizer[*]}" =~ $contractFile ]] + then + printTask " - ${contractFile}" + test_via_ir_equivalence "$(cat "${REPO_ROOT}/test/libsolidity/semanticTests/externalContracts/${contractFile}")" + fi + + printTask " - ${contractFile} (optimized)" + test_via_ir_equivalence "$(cat "${REPO_ROOT}/test/libsolidity/semanticTests/externalContracts/${contractFile}")" --optimize + done +) printTask "Testing standard input..." SOLTMPDIR=$(mktemp -d) From e2e393495eb7cd9fe9410a914ac772aa246f13ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 15 Oct 2021 15:50:52 +0200 Subject: [PATCH 0122/1748] Install diffutils on macOS to get diff with color support --- .circleci/osx_install_dependencies.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index ed11f24913..7ef8635a87 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -57,6 +57,7 @@ then brew install cmake brew install wget brew install coreutils + brew install diffutils ./scripts/install_obsolete_jsoncpp_1_7_4.sh # z3 From d3b246316622a3beb3ca71396584b4389fa8f630 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Wed, 29 Sep 2021 13:05:08 -0700 Subject: [PATCH 0123/1748] Improve description of literal evaluation. --- docs/yul.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/yul.rst b/docs/yul.rst index 8f59f28115..ef44a575ba 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -714,13 +714,15 @@ We will use a destructuring notation for the AST nodes. L'[$parami] = vi and L'[$reti] = 0 for all i. Let G'', L'', mode = E(Gn, L', block) G'', Ln, L''[$ret1], ..., L''[$retm] - E(G, L, l: StringLiteral) = G, L, utf8EncodeLeftAligned(l), - where utf8EncodeLeftAligned performs a UTF-8 encoding of l - and aligns it left into 32 bytes + E(G, L, l: StringLiteral) = G, L, str(l), + where str is the string evaluation function, + which for the EVM dialect is defined in the section 'Literals' above E(G, L, n: HexNumber) = G, L, hex(n) - where hex is the hexadecimal decoding function + where hex is the hexadecimal evaluation function, + which turns a sequence of hexadecimal digits into their big endian value E(G, L, n: DecimalNumber) = G, L, dec(n), - where dec is the decimal decoding function + where dec is the decimal evaluation function, + which turns a sequence of decimal digits into their big endian value .. _opcodes: From ab5a06e2b93aa57e84c3bea11561cf429abb19e5 Mon Sep 17 00:00:00 2001 From: Marenz Date: Wed, 27 Oct 2021 13:22:02 +0200 Subject: [PATCH 0124/1748] Refactor ASTJSON tests to allow easier addition of variations. --- test/libsolidity/ASTJSONTest.cpp | 144 +++++++++++++------------------ test/libsolidity/ASTJSONTest.h | 40 +++++++-- 2 files changed, 92 insertions(+), 92 deletions(-) diff --git a/test/libsolidity/ASTJSONTest.cpp b/test/libsolidity/ASTJSONTest.cpp index 8579e9ea4b..82c6e7e186 100644 --- a/test/libsolidity/ASTJSONTest.cpp +++ b/test/libsolidity/ASTJSONTest.cpp @@ -16,17 +16,20 @@ */ // SPDX-License-Identifier: GPL-3.0 -#include -#include -#include -#include #include #include -#include +#include +#include + +#include +#include + #include #include -#include +#include #include +#include + #include #include #include @@ -72,8 +75,13 @@ ASTJSONTest::ASTJSONTest(string const& _filename) if (!boost::algorithm::ends_with(_filename, ".sol")) BOOST_THROW_EXCEPTION(runtime_error("Invalid test contract file name: \"" + _filename + "\".")); - m_astFilename = _filename.substr(0, _filename.size() - 4) + ".json"; - m_astParseOnlyFilename = _filename.substr(0, _filename.size() - 4) + "_parseOnly.json"; + string_view baseName = _filename; + baseName.remove_suffix(4); + + m_variants = { + TestVariant(baseName, CompilerStack::State::Parsed), + TestVariant(baseName, CompilerStack::State::AnalysisPerformed), + }; ifstream file(_filename); if (!file) @@ -102,26 +110,13 @@ ASTJSONTest::ASTJSONTest(string const& _filename) } m_sources.emplace_back(sourceName.empty() ? "a" : sourceName, source); - file.close(); - file.open(m_astFilename); - if (file) - { - string line; - while (getline(file, line)) - m_expectation += line + "\n"; - } - file.close(); - file.open(m_astParseOnlyFilename); - if (file) + for (TestVariant& variant: m_variants) { - string line; - while (getline(file, line)) - m_expectationParseOnly += line + "\n"; + variant.expectation = readFileAsString(variant.astFilename()); + boost::replace_all(variant.expectation, "\r\n", "\n"); } - - file.close(); } TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted) @@ -135,97 +130,76 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi sources[m_sources[i].first] = m_sources[i].second; sourceIndices[m_sources[i].first] = static_cast(i + 1); } - c.setSources(sources); - c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion()); + bool resultsMatch = true; - if (!c.compile(CompilerStack::State::Parsed)) + for (TestVariant& variant: m_variants) { - SourceReferenceFormatter formatter(_stream, c, _formatted, false); - formatter.printErrorInformation(c.errors()); - return TestResult::FatalError; - } + c.reset(); + c.setSources(sources); + c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion()); - bool resultsMatch = runTest( - m_expectationParseOnly, - m_resultParseOnly, - sourceIndices, - c, - "parseOnly", - _stream, - _linePrefix, - _formatted - ); + if (!c.parseAndAnalyze(variant.stopAfter)) + { + // Ignore non-fatal analysis errors, we only want to export. + if (c.state() > CompilerStack::State::Parsed) + continue; - c.reset(); - c.setSources(sources); - c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion()); - if (!c.parse()) - { - // Empty Expectations means we expect failure - if (m_expectation.empty()) - return resultsMatch ? TestResult::Success : TestResult::Failure; + SourceReferenceFormatter formatter(_stream, c, _formatted, false); + formatter.printErrorInformation(c.errors()); + return TestResult::FatalError; + } - SourceReferenceFormatter{_stream, c, _formatted, false} - .printErrorInformation(c.errors()); - return TestResult::FatalError; + resultsMatch = resultsMatch && runTest( + variant, + sourceIndices, + c, + _stream, + _linePrefix, + _formatted + ); } - c.analyze(); - - resultsMatch = runTest( - m_expectation, - m_result, - sourceIndices, - c, - "", - _stream, - _linePrefix, - _formatted - ) && resultsMatch; - return resultsMatch ? TestResult::Success : TestResult::Failure; } bool ASTJSONTest::runTest( - string& _expectation, - string& _result, + TestVariant& _variant, map const& _sourceIndices, CompilerStack& _compiler, - string const& _variation, ostream& _stream, string const& _linePrefix, bool const _formatted ) { if (m_sources.size() > 1) - _result += "[\n"; + _variant.result += "[\n"; for (size_t i = 0; i < m_sources.size(); i++) { ostringstream result; ASTJsonConverter(_compiler.state(), _sourceIndices).print(result, _compiler.ast(m_sources[i].first)); - _result += result.str(); + _variant.result += result.str(); if (i != m_sources.size() - 1) - _result += ","; - _result += "\n"; + _variant.result += ","; + _variant.result += "\n"; } if (m_sources.size() > 1) - _result += "]\n"; + _variant.result += "]\n"; - replaceTagWithVersion(_expectation); + replaceTagWithVersion(_variant.expectation); - if (_expectation != _result) + if (_variant.expectation != _variant.result) { string nextIndentLevel = _linePrefix + " "; AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result" << - (!_variation.empty() ? " (" + _variation + "):" : ":") << + (!_variant.name().empty() ? " (" + _variant.name() + "):" : ":") << endl; { - istringstream stream(_expectation); + istringstream stream(_variant.expectation); string line; while (getline(stream, line)) _stream << nextIndentLevel << line << endl; @@ -235,10 +209,10 @@ bool ASTJSONTest::runTest( AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result" << - (!_variation.empty() ? " (" + _variation + "):" : ":") << + (!_variant.name().empty() ? " (" + _variant.name() + "):" : ":") << endl; { - istringstream stream(_result); + istringstream stream(_variant.result); string line; while (getline(stream, line)) _stream << nextIndentLevel << line << endl; @@ -266,14 +240,18 @@ void ASTJSONTest::printSource(ostream& _stream, string const& _linePrefix, bool void ASTJSONTest::printUpdatedExpectations(std::ostream&, std::string const&) const { - updateExpectation(m_astFilename, m_result, ""); - updateExpectation(m_astParseOnlyFilename, m_resultParseOnly, "parseOnly "); + for (TestVariant const& variant: m_variants) + updateExpectation( + variant.astFilename(), + variant.result, + variant.name().empty() ? "" : variant.name() + " " + ); } -void ASTJSONTest::updateExpectation(string const& _filename, string const& _expectation, string const& _variation) const +void ASTJSONTest::updateExpectation(string const& _filename, string const& _expectation, string const& _variant) const { ofstream file(_filename.c_str()); - if (!file) BOOST_THROW_EXCEPTION(runtime_error("Cannot write " + _variation + "AST expectation to \"" + _filename + "\".")); + if (!file) BOOST_THROW_EXCEPTION(runtime_error("Cannot write " + _variant + "AST expectation to \"" + _filename + "\".")); file.exceptions(ios::badbit); string replacedResult = _expectation; diff --git a/test/libsolidity/ASTJSONTest.h b/test/libsolidity/ASTJSONTest.h index ac57277ac3..3365de589d 100644 --- a/test/libsolidity/ASTJSONTest.h +++ b/test/libsolidity/ASTJSONTest.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -37,6 +38,32 @@ namespace solidity::frontend::test class ASTJSONTest: public TestCase { public: + struct TestVariant + { + TestVariant(std::string_view _baseName, CompilerStack::State _stopAfter): + baseName(_baseName), + stopAfter(_stopAfter) + {} + + std::string name() const + { + return stopAfter == CompilerStack::State::Parsed ? "parseOnly" : ""; + } + + std::string astFilename() const + { + return std::string(baseName) + + (name().empty() ? "" : "_") + + name() + + ".json"; + } + + std::string baseName; + CompilerStack::State stopAfter; + std::string result; + std::string expectation; + }; + static std::unique_ptr create(Config const& _config) { return std::make_unique(_config.filename); @@ -49,11 +76,9 @@ class ASTJSONTest: public TestCase void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override; private: bool runTest( - std::string& _expectation, - std::string& _result, + TestVariant& _testVariant, std::map const& _sourceIndices, CompilerStack& _compiler, - std::string const& _variation, std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false @@ -61,15 +86,12 @@ class ASTJSONTest: public TestCase void updateExpectation( std::string const& _filename, std::string const& _expectation, - std::string const& _variation + std::string const& _variant ) const; + std::vector m_variants; + std::vector> m_sources; - std::string m_expectationParseOnly; - std::string m_astFilename; - std::string m_astParseOnlyFilename; - std::string m_result; - std::string m_resultParseOnly; }; } From 49b4e77d6ba14aafd701b6f149227b7d138824f3 Mon Sep 17 00:00:00 2001 From: Marenz Date: Tue, 26 Oct 2021 14:03:23 +0200 Subject: [PATCH 0125/1748] Prevent crash when translating yul->ewasm with @use-src annotations --- Changelog.md | 1 + libyul/backends/wasm/EVMToEwasmTranslator.cpp | 6 +++- .../yul_to_wasm_source_location_crash/args | 1 + .../yul_to_wasm_source_location_crash/err | 1 + .../input.yul | 4 +++ .../yul_to_wasm_source_location_crash/output | 34 +++++++++++++++++++ 6 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 test/cmdlineTests/yul_to_wasm_source_location_crash/args create mode 100644 test/cmdlineTests/yul_to_wasm_source_location_crash/err create mode 100644 test/cmdlineTests/yul_to_wasm_source_location_crash/input.yul create mode 100644 test/cmdlineTests/yul_to_wasm_source_location_crash/output diff --git a/Changelog.md b/Changelog.md index 79d5df058c..b3af54d047 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: Bugfixes: + * Code Generator: Fix a crash when using ``@use-src`` and compiling from Yul to ewasm. ### 0.8.10 (2021-11-09) diff --git a/libyul/backends/wasm/EVMToEwasmTranslator.cpp b/libyul/backends/wasm/EVMToEwasmTranslator.cpp index eb7a60a32f..359cc023bb 100644 --- a/libyul/backends/wasm/EVMToEwasmTranslator.cpp +++ b/libyul/backends/wasm/EVMToEwasmTranslator.cpp @@ -137,7 +137,11 @@ void EVMToEwasmTranslator::parsePolyfill() string(solidity::yul::wasm::polyfill::Logical) + string(solidity::yul::wasm::polyfill::Memory) + "}", ""); - m_polyfill = Parser(errorReporter, WasmDialect::instance()).parse(charStream); + + // Passing an empty SourceLocation() here is a workaround to prevent a crash + // when compiling from yul->ewasm. We're stripping nativeLocation and + // originLocation from the AST (but we only really need to strip nativeLocation) + m_polyfill = Parser(errorReporter, WasmDialect::instance(), langutil::SourceLocation()).parse(charStream); if (!errors.empty()) { string message; diff --git a/test/cmdlineTests/yul_to_wasm_source_location_crash/args b/test/cmdlineTests/yul_to_wasm_source_location_crash/args new file mode 100644 index 0000000000..254a1883c1 --- /dev/null +++ b/test/cmdlineTests/yul_to_wasm_source_location_crash/args @@ -0,0 +1 @@ +--strict-assembly --yul-dialect evm --machine ewasm --optimize --ewasm-ir diff --git a/test/cmdlineTests/yul_to_wasm_source_location_crash/err b/test/cmdlineTests/yul_to_wasm_source_location_crash/err new file mode 100644 index 0000000000..014a1178fa --- /dev/null +++ b/test/cmdlineTests/yul_to_wasm_source_location_crash/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/yul_to_wasm_source_location_crash/input.yul b/test/cmdlineTests/yul_to_wasm_source_location_crash/input.yul new file mode 100644 index 0000000000..89e060931b --- /dev/null +++ b/test/cmdlineTests/yul_to_wasm_source_location_crash/input.yul @@ -0,0 +1,4 @@ +/// @use-src 0:"test.sol" +object "C" { + code { sstore(0,0) } +} diff --git a/test/cmdlineTests/yul_to_wasm_source_location_crash/output b/test/cmdlineTests/yul_to_wasm_source_location_crash/output new file mode 100644 index 0000000000..29ff631aa5 --- /dev/null +++ b/test/cmdlineTests/yul_to_wasm_source_location_crash/output @@ -0,0 +1,34 @@ + +======= yul_to_wasm_source_location_crash/input.yul (Ewasm) ======= + +========================== + +Translated source: +/// @use-src 0:"test.sol" +object "C" { + code { + function main() + { + let hi := i64.shl(i64.extend_i32_u(bswap32(i32.wrap_i64(0))), 32) + let y := i64.or(hi, i64.extend_i32_u(bswap32(i32.wrap_i64(i64.shr_u(0, 32))))) + i64.store(0:i32, y) + i64.store(i32.add(0:i32, 8:i32), y) + i64.store(i32.add(0:i32, 16:i32), y) + i64.store(i32.add(0:i32, 24:i32), y) + i64.store(32:i32, y) + i64.store(i32.add(32:i32, 8:i32), y) + i64.store(i32.add(32:i32, 16:i32), y) + i64.store(i32.add(32:i32, 24:i32), y) + eth.storageStore(0:i32, 32:i32) + } + function bswap16(x:i32) -> y:i32 + { + y := i32.or(i32.and(i32.shl(x, 8:i32), 0xff00:i32), i32.and(i32.shr_u(x, 8:i32), 0xff:i32)) + } + function bswap32(x:i32) -> y:i32 + { + let hi:i32 := i32.shl(bswap16(x), 16:i32) + y := i32.or(hi, bswap16(i32.shr_u(x, 16:i32))) + } + } +} From cf528271079c3eb3c2d43d1cf72a67998af3dd37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 15 Nov 2021 14:29:22 +0100 Subject: [PATCH 0126/1748] Fix gas mismatch in constructor not being counted as a failure --- test/libsolidity/SemanticTest.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index c5ee04044d..963967ca48 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -407,7 +407,10 @@ TestCase::TestResult SemanticTest::runTest( if (m_transactionSuccessful == test.call().expectations.failure) success = false; if (success && !checkGasCostExpectation(test, _isYulRun)) + { + success = false; m_gasCostFailure = true; + } test.setFailure(!m_transactionSuccessful); test.setRawBytes(bytes()); From 077b3a003d65e498e2bc7f5d0f421aba75d451f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 15 Nov 2021 14:36:13 +0100 Subject: [PATCH 0127/1748] Fix `--enforce-gas-cost-min-value` being applied only when the cost expectations are not provided in the test file --- test/libsolidity/SemanticTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 963967ca48..ad6f40fbb6 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -565,14 +565,14 @@ bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _comp // We don't check gas if enforce gas cost is not active // or test is run with abi encoder v1 only // or gas used less than threshold for enforcing feature + // or the test has used up all available gas (test will fail anyway) // or setting is "ir" and it's not included in expectations // or if the called function is an isoltest builtin e.g. `smokeTest` or `storageEmpty` if ( !m_enforceGasCost || - ( - (setting == "ir" || m_gasUsed < m_enforceGasCostMinValue || m_gasUsed >= m_gas) && - io_test.call().expectations.gasUsed.count(setting) == 0 - ) || + m_gasUsed < m_enforceGasCostMinValue || + m_gasUsed >= m_gas || + (setting == "ir" && io_test.call().expectations.gasUsed.count(setting) == 0) || io_test.call().kind == FunctionCall::Kind::Builtin ) return true; From f42180ef06d1bc101829f569fc8d133a1ed42588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 15 Nov 2021 14:42:10 +0100 Subject: [PATCH 0128/1748] Rename gas constants in ExecutionFramework --- test/ExecutionFramework.cpp | 6 +++--- test/ExecutionFramework.h | 5 +++-- test/libsolidity/SemanticTest.cpp | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/test/ExecutionFramework.cpp b/test/ExecutionFramework.cpp index c153cd4717..600bedbf5e 100644 --- a/test/ExecutionFramework.cpp +++ b/test/ExecutionFramework.cpp @@ -182,7 +182,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 message.kind = EVMC_CALL; message.destination = EVMHost::convertToEVMC(m_contractAddress); } - message.gas = m_gas.convert_to(); + message.gas = InitialGas.convert_to(); evmc::result result = m_evmcHost->call(message); @@ -190,7 +190,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 if (_isCreation) m_contractAddress = EVMHost::convertFromEVMC(result.create_address); - m_gasUsed = m_gas - result.gas_left; + m_gasUsed = InitialGas - result.gas_left; m_transactionSuccessful = (result.status_code == EVMC_SUCCESS); if (m_showMessages) @@ -216,7 +216,7 @@ void ExecutionFramework::sendEther(h160 const& _addr, u256 const& _amount) message.value = EVMHost::convertToEVMC(_amount); message.kind = EVMC_CALL; message.destination = EVMHost::convertToEVMC(_addr); - message.gas = m_gas.convert_to(); + message.gas = InitialGas.convert_to(); m_evmcHost->call(message); } diff --git a/test/ExecutionFramework.h b/test/ExecutionFramework.h index 0ee0214d4c..53a09eaf8e 100644 --- a/test/ExecutionFramework.h +++ b/test/ExecutionFramework.h @@ -273,6 +273,9 @@ class ExecutionFramework } protected: + u256 const GasPrice = 10 * gwei; + u256 const InitialGas = 100000000; + void selectVM(evmc_capabilities _cap = evmc_capabilities::EVMC_CAPABILITY_EVM1); void reset(); @@ -302,8 +305,6 @@ class ExecutionFramework bool m_transactionSuccessful = true; util::h160 m_sender = account(0); util::h160 m_contractAddress; - u256 const m_gasPrice = 10 * gwei; - u256 const m_gas = 100000000; bytes m_output; u256 m_gasUsed; }; diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index ad6f40fbb6..4fbb16614c 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -571,7 +571,7 @@ bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _comp if ( !m_enforceGasCost || m_gasUsed < m_enforceGasCostMinValue || - m_gasUsed >= m_gas || + m_gasUsed >= InitialGas || (setting == "ir" && io_test.call().expectations.gasUsed.count(setting) == 0) || io_test.call().kind == FunctionCall::Kind::Builtin ) From 032f2d8f9fc71c6ef4dbe37914c21fe42fb99e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 15 Nov 2021 16:19:33 +0100 Subject: [PATCH 0129/1748] Update gas expectations --- .../semanticTests/array/constant_var_as_array_length.sol | 3 +++ .../semanticTests/array/fixed_arrays_in_constructors.sol | 3 +++ .../constructor/bytes_in_constructors_unpacker.sol | 3 +++ .../constructor/constructor_arguments_external.sol | 3 +++ .../constructor/constructor_static_array_argument.sol | 3 +++ .../semanticTests/constructor_ihneritance_init_order_2.sol | 3 +++ .../semanticTests/constructor_inheritance_init_order.sol | 1 + test/libsolidity/semanticTests/constructor_with_params.sol | 2 ++ .../constructor_with_params_diamond_inheritance.sol | 3 +++ .../semanticTests/constructor_with_params_inheritance.sol | 3 +++ .../semanticTests/events/event_emit_from_other_contract.sol | 4 +++- .../semanticTests/events/event_signature_in_library.sol | 2 +- .../semanticTests/externalContracts/FixedFeeRegistrar.sol | 2 +- .../semanticTests/externalContracts/deposit_contract.sol | 6 +++--- .../semanticTests/externalContracts/prbmath_signed.sol | 4 ++-- .../semanticTests/externalContracts/prbmath_unsigned.sol | 2 +- .../semanticTests/externalContracts/ramanujan_pi.sol | 2 +- .../libsolidity/semanticTests/externalContracts/strings.sol | 2 +- .../functionCall/creation_function_call_with_args.sol | 3 +++ .../functionCall/creation_function_call_with_salt.sol | 3 +++ .../functionCall/external_call_to_nonexisting.sol | 3 ++- .../external_call_to_nonexisting_debugstrings.sol | 2 ++ .../semanticTests/functionCall/gas_and_value_basic.sol | 3 +++ .../functionCall/gas_and_value_brace_syntax.sol | 3 +++ .../semanticTests/functionCall/send_zero_ether.sol | 3 +++ test/libsolidity/semanticTests/immutable/use_scratch.sol | 3 +++ .../semanticTests/inheritance/value_for_constructor.sol | 3 +++ .../isoltestTesting/balance_other_contract.sol | 6 +++--- test/libsolidity/semanticTests/smoke/constructor.sol | 4 +++- test/libsolidity/semanticTests/state/blockhash_basic.sol | 3 +++ .../semanticTests/userDefinedValueType/erc20.sol | 2 +- test/libsolidity/semanticTests/various/address_code.sol | 5 ++++- test/libsolidity/semanticTests/various/code_length.sol | 3 ++- .../semanticTests/various/codebalance_assembly.sol | 1 + .../semanticTests/various/contract_binary_dependencies.sol | 1 + .../semanticTests/various/negative_stack_height.sol | 2 ++ test/libsolidity/semanticTests/various/senders_balance.sol | 3 +++ test/libsolidity/semanticTests/various/value_complex.sol | 3 +++ test/libsolidity/semanticTests/various/value_insane.sol | 3 +++ 39 files changed, 94 insertions(+), 19 deletions(-) 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 c696002ad3..945de3cfea 100644 --- a/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol +++ b/test/libsolidity/semanticTests/array/constant_var_as_array_length.sol @@ -11,6 +11,9 @@ contract C { // compileViaYul: also // ---- // constructor(): 1, 2, 3 -> +// gas irOptimized: 143598 +// gas legacy: 183490 +// gas legacyOptimized: 151938 // a(uint256): 0 -> 1 // a(uint256): 1 -> 2 // a(uint256): 2 -> 3 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol b/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol index c6e46a7fad..ddead0503b 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol @@ -11,5 +11,8 @@ contract Creator { // compileViaYul: also // ---- // constructor(): 1, 2, 3, 4 -> +// gas irOptimized: 132278 +// gas legacy: 176789 +// gas legacyOptimized: 129585 // r() -> 4 // ch() -> 3 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol index e81755ff94..1a93f53b3f 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol @@ -10,5 +10,8 @@ contract Test { // compileViaYul: also // ---- // constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> +// gas irOptimized: 291443 +// gas legacy: 309842 +// gas legacyOptimized: 260801 // 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 bb271ec174..6ee258bd6b 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol @@ -19,5 +19,8 @@ contract Main { // compileViaYul: also // ---- // constructor(): "abc", true +// gas irOptimized: 112563 +// gas legacy: 145838 +// gas legacyOptimized: 104017 // 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 099202c956..ab90a0bb91 100644 --- a/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol +++ b/test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol @@ -12,6 +12,9 @@ contract C { // compileViaYul: also // ---- // constructor(): 1, 2, 3, 4 -> +// gas irOptimized: 180731 +// gas legacy: 221377 +// gas legacyOptimized: 177671 // a() -> 1 // b(uint256): 0 -> 2 // b(uint256): 1 -> 3 diff --git a/test/libsolidity/semanticTests/constructor_ihneritance_init_order_2.sol b/test/libsolidity/semanticTests/constructor_ihneritance_init_order_2.sol index 44a7fb2f3b..db58499ea4 100644 --- a/test/libsolidity/semanticTests/constructor_ihneritance_init_order_2.sol +++ b/test/libsolidity/semanticTests/constructor_ihneritance_init_order_2.sol @@ -12,4 +12,7 @@ contract B is A { // compileViaYul: also // ---- // constructor() -> +// gas irOptimized: 122233 +// gas legacy: 135046 +// gas legacyOptimized: 116176 // y() -> 42 diff --git a/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol b/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol index 757a5481f7..41a050fc40 100644 --- a/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol +++ b/test/libsolidity/semanticTests/constructor_inheritance_init_order.sol @@ -15,4 +15,5 @@ contract B is A { // compileViaYul: true // ---- // constructor() -> +// gas irOptimized: 122233 // y() -> 42 diff --git a/test/libsolidity/semanticTests/constructor_with_params.sol b/test/libsolidity/semanticTests/constructor_with_params.sol index e3ac5b386c..cb61927745 100644 --- a/test/libsolidity/semanticTests/constructor_with_params.sol +++ b/test/libsolidity/semanticTests/constructor_with_params.sol @@ -11,5 +11,7 @@ contract C { // compileViaYul: also // ---- // constructor(): 2, 0 -> +// gas irOptimized: 104227 +// gas legacy: 117158 // 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 89cb202c60..fe3c95b544 100644 --- a/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol +++ b/test/libsolidity/semanticTests/constructor_with_params_diamond_inheritance.sol @@ -23,6 +23,9 @@ contract D is B, C { // compileViaYul: also // ---- // constructor(): 2, 0 -> +// gas irOptimized: 159542 +// gas legacy: 170665 +// gas legacyOptimized: 145396 // 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 d477bbc0d9..3d90783f82 100644 --- a/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol +++ b/test/libsolidity/semanticTests/constructor_with_params_inheritance.sol @@ -14,5 +14,8 @@ contract D is C { // compileViaYul: also // ---- // constructor(): 2, 0 -> +// gas irOptimized: 124844 +// gas legacy: 139250 +// gas legacyOptimized: 119367 // 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 128cf00ea3..690f555dc6 100644 --- a/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol +++ b/test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol @@ -17,6 +17,8 @@ contract C { // compileViaYul: also // ---- // constructor() -> -// gas legacy: 249112 +// gas irOptimized: 177344 +// gas legacy: 250376 +// gas legacyOptimized: 174522 // deposit(bytes32), 18 wei: 0x1234 -> // ~ emit Deposit(address,bytes32,uint256) from 0xf01f7809444bd9a93a854361c6fae3f23d9e23db: #0x0fdd67305928fcac8d213d1e47bfa6165cd0b87b, #0x1234, 0x00 diff --git a/test/libsolidity/semanticTests/events/event_signature_in_library.sol b/test/libsolidity/semanticTests/events/event_signature_in_library.sol index e43fc4c645..b301ebfd5a 100644 --- a/test/libsolidity/semanticTests/events/event_signature_in_library.sol +++ b/test/libsolidity/semanticTests/events/event_signature_in_library.sol @@ -20,4 +20,4 @@ contract C { // ---- // constructor() // ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00 -// gas legacy: 150662 +// gas legacy: 150602 diff --git a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol index 9205de434d..fc0b416fde 100644 --- a/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol +++ b/test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol @@ -76,7 +76,7 @@ contract FixedFeeRegistrar is Registrar { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 425623 +// gas irOptimized: 426283 // gas legacy: 936897 // gas legacyOptimized: 490983 // reserve(string), 69 ether: 0x20, 3, "abc" -> diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index f054497e98..ed9a07f7ff 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -178,9 +178,9 @@ contract DepositContract is IDepositContract, ERC165 { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 1558013 -// gas legacy: 2580394 -// gas legacyOptimized: 1775403 +// gas irOptimized: 1558001 +// gas legacy: 2436584 +// gas legacyOptimized: 1776483 // 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 01d2403a6d..9de7a30d81 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol @@ -50,8 +50,8 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 1924584 -// gas legacy: 2602700 +// gas irOptimized: 1924392 +// gas legacy: 2480887 // gas legacyOptimized: 1874490 // div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 // gas irOptimized: 22137 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol index c31664c859..11001fffad 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol @@ -51,7 +51,7 @@ contract test { // ---- // constructor() // gas irOptimized: 1778342 -// gas legacy: 2356230 +// gas legacy: 2250130 // gas legacyOptimized: 1746528 // div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 // gas irOptimized: 22004 diff --git a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol index 1fc85adff7..763a8acdaf 100644 --- a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol +++ b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol @@ -36,7 +36,7 @@ contract test { // ---- // constructor() // gas irOptimized: 465357 -// gas legacy: 733634 +// gas legacy: 672749 // gas legacyOptimized: 479606 // prb_pi() -> 3141592656369545286 // gas irOptimized: 57478 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index 238ed21840..7c4028bb9f 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -52,7 +52,7 @@ contract test { // ---- // constructor() // gas irOptimized: 702619 -// gas legacy: 1188228 +// gas legacy: 1130761 // gas legacyOptimized: 750416 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 // gas irOptimized: 22660 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 56e458110d..2da7c2dd6d 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol @@ -17,4 +17,7 @@ contract D { // compileViaYul: also // ---- // constructor(): 2 -> +// gas irOptimized: 200295 +// gas legacy: 245842 +// gas legacyOptimized: 195676 // 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 725a54b547..0b0633c6d1 100644 --- a/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol +++ b/test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol @@ -18,4 +18,7 @@ contract D { // compileViaYul: also // ---- // constructor(): 2 -> +// gas irOptimized: 200458 +// gas legacy: 246202 +// gas legacyOptimized: 195914 // 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 9546f10986..942faa048b 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol @@ -25,8 +25,9 @@ contract C { // compileViaYul: also // ---- // constructor(), 1 ether -> +// gas irOptimized: 308423 // gas legacy: 465314 -// gas legacyOptimized: 510004 +// gas legacyOptimized: 304481 // 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 f426e628eb..26faf248ff 100644 --- a/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol +++ b/test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol @@ -27,6 +27,8 @@ contract C { // revertStrings: debug // ---- // constructor(), 1 ether -> +// gas irOptimized: 448383 +// gas legacy: 834272 // gas legacyOptimized: 510004 // f(uint256): 0 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" // f(uint256): 1 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" diff --git a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol index 5ca46b4e19..b1d9299d88 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol @@ -41,6 +41,9 @@ contract test { // compileViaYul: also // ---- // constructor(), 20 wei -> +// gas irOptimized: 285350 +// gas legacy: 402654 +// gas legacyOptimized: 274470 // 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 3da540807c..9e2491ac1b 100644 --- a/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol +++ b/test/libsolidity/semanticTests/functionCall/gas_and_value_brace_syntax.sol @@ -40,6 +40,9 @@ contract test { // compileViaYul: also // ---- // constructor(), 20 wei -> +// gas irOptimized: 285350 +// gas legacy: 402654 +// gas legacyOptimized: 274470 // 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 5f821ff3dd..617a6dec28 100644 --- a/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol +++ b/test/libsolidity/semanticTests/functionCall/send_zero_ether.sol @@ -19,4 +19,7 @@ contract Main { // compileViaYul: also // ---- // constructor(), 20 wei -> +// gas irOptimized: 102862 +// gas legacy: 116691 +// gas legacyOptimized: 100361 // s() -> true diff --git a/test/libsolidity/semanticTests/immutable/use_scratch.sol b/test/libsolidity/semanticTests/immutable/use_scratch.sol index 71381fc9b4..4fb3bf2455 100644 --- a/test/libsolidity/semanticTests/immutable/use_scratch.sol +++ b/test/libsolidity/semanticTests/immutable/use_scratch.sol @@ -17,5 +17,8 @@ contract C { // compileViaYul: also // ---- // constructor(): 3 -> +// gas irOptimized: 137184 +// gas legacy: 209361 +// gas legacyOptimized: 139324 // f() -> 84, 23 // m(uint256): 3 -> 7 diff --git a/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol b/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol index 057b3b8e45..b2f0f8a6b1 100644 --- a/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol +++ b/test/libsolidity/semanticTests/inheritance/value_for_constructor.sol @@ -42,6 +42,9 @@ contract Main { // compileViaYul: also // ---- // constructor(), 22 wei -> +// gas irOptimized: 288778 +// gas legacy: 402045 +// gas legacyOptimized: 266772 // 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 59ad2cd84b..5af1e5cdc6 100644 --- a/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol +++ b/test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol @@ -18,9 +18,9 @@ contract ClientReceipt { // compileViaYul: also // ---- // constructor(), 2000 wei -> -// gas irOptimized: 191881 -// gas legacy: 235167 -// gas legacyOptimized: 180756 +// gas irOptimized: 184076 +// gas legacy: 235195 +// gas legacyOptimized: 176766 // balance -> 1500 // gas irOptimized: 191881 // gas legacy: 235167 diff --git a/test/libsolidity/semanticTests/smoke/constructor.sol b/test/libsolidity/semanticTests/smoke/constructor.sol index 3837fe071f..7667c2443f 100644 --- a/test/libsolidity/semanticTests/smoke/constructor.sol +++ b/test/libsolidity/semanticTests/smoke/constructor.sol @@ -14,7 +14,9 @@ contract C { // compileViaYul: also // ---- // constructor(), 2 wei: 3 -> -// gas legacy: 148000 +// gas irOptimized: 111723 +// gas legacy: 151416 +// gas legacyOptimized: 108388 // 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 528c8aea64..d4dbffcb8f 100644 --- a/test/libsolidity/semanticTests/state/blockhash_basic.sol +++ b/test/libsolidity/semanticTests/state/blockhash_basic.sol @@ -14,6 +14,9 @@ contract C { // compileViaYul: also // ---- // constructor() +// gas irOptimized: 119839 +// gas legacy: 155081 +// gas legacyOptimized: 107997 // 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 4db14ff739..efe2ee1148 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol @@ -116,7 +116,7 @@ contract ERC20 { // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 // gas irOptimized: 442239 -// gas legacy: 861547 +// gas legacy: 861559 // gas legacyOptimized: 420959 // totalSupply() -> 20 // gas irOptimized: 23415 diff --git a/test/libsolidity/semanticTests/various/address_code.sol b/test/libsolidity/semanticTests/various/address_code.sol index 8e840fd016..6072d5ac3e 100644 --- a/test/libsolidity/semanticTests/various/address_code.sol +++ b/test/libsolidity/semanticTests/various/address_code.sol @@ -13,10 +13,13 @@ contract C { function h() public view returns (uint) { return address(1).code.length; } } // ==== -// compileViaYul: also // compileToEwasm: also +// compileViaYul: also // ---- // constructor() -> +// gas irOptimized: 199687 +// gas legacy: 241124 +// gas legacyOptimized: 155549 // initCode() -> 0x20, 0 // f() -> true // g() -> 0 diff --git a/test/libsolidity/semanticTests/various/code_length.sol b/test/libsolidity/semanticTests/various/code_length.sol index 53b3534b25..ad4b6f874c 100644 --- a/test/libsolidity/semanticTests/various/code_length.sol +++ b/test/libsolidity/semanticTests/various/code_length.sol @@ -58,8 +58,9 @@ contract C { } } // ==== -// compileViaYul: also // compileToEwasm: also +// compileViaYul: also // ---- // constructor() +// gas legacy: 126455 // f(): true, true -> true, true diff --git a/test/libsolidity/semanticTests/various/codebalance_assembly.sol b/test/libsolidity/semanticTests/various/codebalance_assembly.sol index 2df9c5b4f2..98f4e29693 100644 --- a/test/libsolidity/semanticTests/various/codebalance_assembly.sol +++ b/test/libsolidity/semanticTests/various/codebalance_assembly.sol @@ -23,6 +23,7 @@ contract C { // compileViaYul: also // ---- // constructor(), 23 wei -> +// gas legacy: 100517 // f() -> 0 // g() -> 1 // h() -> 23 diff --git a/test/libsolidity/semanticTests/various/contract_binary_dependencies.sol b/test/libsolidity/semanticTests/various/contract_binary_dependencies.sol index 5303cdd52c..57942979ae 100644 --- a/test/libsolidity/semanticTests/various/contract_binary_dependencies.sol +++ b/test/libsolidity/semanticTests/various/contract_binary_dependencies.sol @@ -21,3 +21,4 @@ contract C { // compileViaYul: also // ---- // constructor() -> +// gas irOptimized: 104337 diff --git a/test/libsolidity/semanticTests/various/negative_stack_height.sol b/test/libsolidity/semanticTests/various/negative_stack_height.sol index ba1bebc18d..52fce16f51 100644 --- a/test/libsolidity/semanticTests/various/negative_stack_height.sol +++ b/test/libsolidity/semanticTests/various/negative_stack_height.sol @@ -65,3 +65,5 @@ contract C { // compileViaYul: false // ---- // constructor() -> +// gas legacy: 588138 +// gas legacyOptimized: 349636 diff --git a/test/libsolidity/semanticTests/various/senders_balance.sol b/test/libsolidity/semanticTests/various/senders_balance.sol index 08b83401c0..600e72e3e3 100644 --- a/test/libsolidity/semanticTests/various/senders_balance.sol +++ b/test/libsolidity/semanticTests/various/senders_balance.sol @@ -19,4 +19,7 @@ contract D { // compileViaYul: also // ---- // constructor(), 27 wei -> +// gas irOptimized: 175261 +// gas legacy: 222977 +// gas legacyOptimized: 169779 // f() -> 27 diff --git a/test/libsolidity/semanticTests/various/value_complex.sol b/test/libsolidity/semanticTests/various/value_complex.sol index 8d091ec982..bebf7557f0 100644 --- a/test/libsolidity/semanticTests/various/value_complex.sol +++ b/test/libsolidity/semanticTests/various/value_complex.sol @@ -22,4 +22,7 @@ contract test { // compileViaYul: also // ---- // constructor(), 20 wei -> +// gas irOptimized: 185891 +// gas legacy: 265006 +// gas legacyOptimized: 182842 // sendAmount(uint256): 5 -> 8 diff --git a/test/libsolidity/semanticTests/various/value_insane.sol b/test/libsolidity/semanticTests/various/value_insane.sol index c81570626c..9edd8061a1 100644 --- a/test/libsolidity/semanticTests/various/value_insane.sol +++ b/test/libsolidity/semanticTests/various/value_insane.sol @@ -21,4 +21,7 @@ contract test { // compileViaYul: also // ---- // constructor(), 20 wei -> +// gas irOptimized: 187835 +// gas legacy: 266728 +// gas legacyOptimized: 184762 // sendAmount(uint256): 5 -> 8 From 27dc77be5ddc8cb18009b9611b831bf75e5f4536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 15 Nov 2021 16:32:38 +0100 Subject: [PATCH 0130/1748] Fix typo in test name: ihneritance -> inheritance --- ..._init_order_2.sol => constructor_inheritance_init_order_2.sol} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/libsolidity/semanticTests/{constructor_ihneritance_init_order_2.sol => constructor_inheritance_init_order_2.sol} (100%) diff --git a/test/libsolidity/semanticTests/constructor_ihneritance_init_order_2.sol b/test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol similarity index 100% rename from test/libsolidity/semanticTests/constructor_ihneritance_init_order_2.sol rename to test/libsolidity/semanticTests/constructor_inheritance_init_order_2.sol From 90fdea95e7a0cf5a8c29e054afb02018cf7a257d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 15 Nov 2021 19:58:59 +0100 Subject: [PATCH 0131/1748] TestFunctionCall::formatRawParameters(): Ensure that uint8_t overload of toHex() is called - Wrong overload results in isoltest padding each char to 32 bytes --- .../format_raw_string_with_control_chars.sol | 12 ++++++++++++ test/libsolidity/util/BytesUtils.cpp | 2 +- test/libsolidity/util/TestFunctionCall.cpp | 4 +++- 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/semanticTests/isoltestTesting/format_raw_string_with_control_chars.sol diff --git a/test/libsolidity/semanticTests/isoltestTesting/format_raw_string_with_control_chars.sol b/test/libsolidity/semanticTests/isoltestTesting/format_raw_string_with_control_chars.sol new file mode 100644 index 0000000000..205a4ae3dd --- /dev/null +++ b/test/libsolidity/semanticTests/isoltestTesting/format_raw_string_with_control_chars.sol @@ -0,0 +1,12 @@ +contract C { + function f(string memory s) external pure returns (string memory) { + return s; + } +} +// NOTE: The test is here to illustrate the problem with formatting control chars in strings in +// test expectations but unfortunately it can only be triggered manually. It does not test anything +// unless you introduce a difference in expectations to force isoltest to reformat them. +// ==== +// compileViaYul: also +// ---- +// f(string): 0x20, 16, "\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83" -> 0x20, 16, "\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83" # Input/Output: "😃😃😃😃" # diff --git a/test/libsolidity/util/BytesUtils.cpp b/test/libsolidity/util/BytesUtils.cpp index 6745bd1dfc..f74b256d0c 100644 --- a/test/libsolidity/util/BytesUtils.cpp +++ b/test/libsolidity/util/BytesUtils.cpp @@ -219,7 +219,7 @@ string BytesUtils::formatString(bytes const& _bytes, size_t _cutOff) if (isprint(v)) os << v; else - os << "\\x" << toHex(v); + os << "\\x" << toHex(v, HexCase::Lower); } } os << "\""; diff --git a/test/libsolidity/util/TestFunctionCall.cpp b/test/libsolidity/util/TestFunctionCall.cpp index 0f28f3b99b..43805c8f99 100644 --- a/test/libsolidity/util/TestFunctionCall.cpp +++ b/test/libsolidity/util/TestFunctionCall.cpp @@ -322,7 +322,9 @@ string TestFunctionCall::formatRawParameters( if (param.format.newline) os << endl << _linePrefix << "// "; for (auto const c: param.rawString) - os << (c >= ' ' ? string(1, c) : "\\x" + toHex(static_cast(c))); + // NOTE: Even though we have a toHex() overload specifically for uint8_t, the compiler + // chooses the one for bytes if the second argument is omitted. + os << (c >= ' ' ? string(1, c) : "\\x" + toHex(static_cast(c), HexCase::Lower)); if (¶m != &_params.back()) os << ", "; } From b36a3c6bf58cd4061e14bc03819d21536372b0ea Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sat, 20 Nov 2021 22:41:19 +0000 Subject: [PATCH 0132/1748] Fix documentation for valid ASCII string literals --- 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 f849f3f7eb..4cb0dec4fa 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -507,7 +507,7 @@ String literals are written with either double or single-quotes (``"foo"`` or `` For example, with ``bytes32 samevar = "stringliteral"`` the string literal is interpreted in its raw byte form when assigned to a ``bytes32`` type. -String literals can only contain printable ASCII characters, which means the characters between and including 0x1F .. 0x7E. +String literals can only contain printable ASCII characters, which means the characters between and including 0x20 .. 0x7E. Additionally, string literals also support the following escape characters: From ef3c562160b4e86da8ce5644e1d1ceb51e2b5a93 Mon Sep 17 00:00:00 2001 From: Dallon Asnes <30935722+dallonasnes@users.noreply.github.com> Date: Mon, 22 Nov 2021 15:18:43 -0600 Subject: [PATCH 0133/1748] Fix typo --- docs/introduction-to-smart-contracts.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index d19a0decf8..c448d7671d 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -584,5 +584,5 @@ but instead is implemented in the EVM execution environment itself. Different EVM-compatible chains might use a different set of precompiled contracts. It might also be possible that new precompiled contracts are added to the Ethereum main chain in the future, -but you can reasonabyly expect them to always be in the range between -``1`` and ``0xffff`` (inclusive). \ No newline at end of file +but you can reasonably expect them to always be in the range between +``1`` and ``0xffff`` (inclusive). From bd321b9f1f3b4e5527dc4958cc2b1c82c84e1c3f Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 23 Nov 2021 10:37:12 +0100 Subject: [PATCH 0134/1748] Rename RedundantAssignEliminator to UnusedAssignEliminator. --- libyul/CMakeLists.txt | 8 ++--- libyul/optimiser/SSATransform.h | 2 +- libyul/optimiser/Suite.cpp | 6 ++-- ...minator.cpp => UnusedAssignEliminator.cpp} | 36 +++++++++---------- ...nEliminator.h => UnusedAssignEliminator.h} | 10 +++--- ...ndantStoreBase.cpp => UnusedStoreBase.cpp} | 20 +++++------ ...RedundantStoreBase.h => UnusedStoreBase.h} | 8 ++--- test/libyul/YulOptimizerTestCommon.cpp | 10 +++--- .../for.yul | 0 .../for_branch.yul | 0 .../for_break.yul | 0 .../for_continue.yul | 0 .../for_continue_2.yul | 0 .../for_continue_3.yul | 0 .../for_decl_inside_break_continue.yul | 0 .../for_deep_noremove.yul | 0 .../for_deep_simple.yul | 0 .../for_multi_break.yul | 0 .../for_nested.yul | 0 .../for_rerun.yul | 0 .../for_stmnts_after_break_continue.yul | 0 .../function.yul | 0 .../if.yul | 0 .../if_overwrite_all_branches.yul | 0 .../if_used_in_one_branch.yul | 0 .../leave.yul | 0 .../multi_assign.yul | 0 .../multivar.yul | 0 .../non_movable.yul | 0 .../remove_break.yul | 0 .../remove_continue.yul | 0 .../scopes.yul | 0 .../simple.yul | 0 .../switch_overwrite_in_all.yul | 0 .../switch_overwrite_in_one.yul | 0 .../switch_overwrite_use_combination.yul | 0 .../switch_unused.yul | 0 test/yulPhaser/Chromosome.cpp | 4 +-- 38 files changed, 52 insertions(+), 52 deletions(-) rename libyul/optimiser/{RedundantAssignEliminator.cpp => UnusedAssignEliminator.cpp} (74%) rename libyul/optimiser/{RedundantAssignEliminator.h => UnusedAssignEliminator.h} (94%) rename libyul/optimiser/{RedundantStoreBase.cpp => UnusedStoreBase.cpp} (86%) rename libyul/optimiser/{RedundantStoreBase.h => UnusedStoreBase.h} (92%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_branch.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_break.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_continue.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_continue_2.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_continue_3.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_decl_inside_break_continue.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_deep_noremove.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_deep_simple.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_multi_break.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_nested.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_rerun.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/for_stmnts_after_break_continue.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/function.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/if.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/if_overwrite_all_branches.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/if_used_in_one_branch.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/leave.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/multi_assign.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/multivar.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/non_movable.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/remove_break.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/remove_continue.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/scopes.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/simple.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/switch_overwrite_in_all.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/switch_overwrite_in_one.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/switch_overwrite_use_combination.yul (100%) rename test/libyul/yulOptimizerTests/{redundantAssignEliminator => unusedAssignEliminator}/switch_unused.yul (100%) diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 039e24ea91..16b68535a9 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -173,10 +173,10 @@ add_library(yul optimiser/OptimizerUtilities.h optimiser/ReasoningBasedSimplifier.cpp optimiser/ReasoningBasedSimplifier.h - optimiser/RedundantAssignEliminator.cpp - optimiser/RedundantAssignEliminator.h - optimiser/RedundantStoreBase.cpp - optimiser/RedundantStoreBase.h + optimiser/UnusedAssignEliminator.cpp + optimiser/UnusedAssignEliminator.h + optimiser/UnusedStoreBase.cpp + optimiser/UnusedStoreBase.h optimiser/Rematerialiser.cpp optimiser/Rematerialiser.h optimiser/SMTSolver.cpp diff --git a/libyul/optimiser/SSATransform.h b/libyul/optimiser/SSATransform.h index 66015362a1..64181bf208 100644 --- a/libyul/optimiser/SSATransform.h +++ b/libyul/optimiser/SSATransform.h @@ -70,7 +70,7 @@ class NameDispenser; * variable references can use the SSA variable. The only exception to this rule are * for loop conditions, as we cannot insert a variable declaration there. * - * After this stage, redundantAssignmentRemover is recommended to remove the unnecessary + * After this stage, UnusedAssignmentEliminator is recommended to remove the unnecessary * intermediate assignments. * * This stage provides best results if CSE is run right before it, because diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 766cc93b90..4012fa9700 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include #include @@ -219,7 +219,7 @@ map> const& OptimiserSuite::allSteps() LiteralRematerialiser, LoadResolver, LoopInvariantCodeMotion, - RedundantAssignEliminator, + UnusedAssignEliminator, ReasoningBasedSimplifier, Rematerialiser, SSAReverser, @@ -260,7 +260,7 @@ map const& OptimiserSuite::stepNameToAbbreviationMap() {LoadResolver::name, 'L'}, {LoopInvariantCodeMotion::name, 'M'}, {ReasoningBasedSimplifier::name, 'R'}, - {RedundantAssignEliminator::name, 'r'}, + {UnusedAssignEliminator::name, 'r'}, {Rematerialiser::name, 'm'}, {SSAReverser::name, 'V'}, {SSATransform::name, 'a'}, diff --git a/libyul/optimiser/RedundantAssignEliminator.cpp b/libyul/optimiser/UnusedAssignEliminator.cpp similarity index 74% rename from libyul/optimiser/RedundantAssignEliminator.cpp rename to libyul/optimiser/UnusedAssignEliminator.cpp index b6ac69c8f0..74dd599a11 100644 --- a/libyul/optimiser/RedundantAssignEliminator.cpp +++ b/libyul/optimiser/UnusedAssignEliminator.cpp @@ -20,7 +20,7 @@ * until they go out of scope or are re-assigned. */ -#include +#include #include #include @@ -33,36 +33,36 @@ using namespace std; using namespace solidity; using namespace solidity::yul; -void RedundantAssignEliminator::run(OptimiserStepContext& _context, Block& _ast) +void UnusedAssignEliminator::run(OptimiserStepContext& _context, Block& _ast) { - RedundantAssignEliminator rae{_context.dialect}; + UnusedAssignEliminator rae{_context.dialect}; rae(_ast); StatementRemover remover{rae.m_pendingRemovals}; remover(_ast); } -void RedundantAssignEliminator::operator()(Identifier const& _identifier) +void UnusedAssignEliminator::operator()(Identifier const& _identifier) { changeUndecidedTo(_identifier.name, State::Used); } -void RedundantAssignEliminator::operator()(VariableDeclaration const& _variableDeclaration) +void UnusedAssignEliminator::operator()(VariableDeclaration const& _variableDeclaration) { - RedundantStoreBase::operator()(_variableDeclaration); + UnusedStoreBase::operator()(_variableDeclaration); for (auto const& var: _variableDeclaration.variables) m_declaredVariables.emplace(var.name); } -void RedundantAssignEliminator::operator()(Assignment const& _assignment) +void UnusedAssignEliminator::operator()(Assignment const& _assignment) { visit(*_assignment.value); for (auto const& var: _assignment.variableNames) changeUndecidedTo(var.name, State::Unused); } -void RedundantAssignEliminator::operator()(FunctionDefinition const& _functionDefinition) +void UnusedAssignEliminator::operator()(FunctionDefinition const& _functionDefinition) { ScopedSaveAndRestore outerDeclaredVariables(m_declaredVariables, {}); ScopedSaveAndRestore outerReturnVariables(m_returnVariables, {}); @@ -70,28 +70,28 @@ void RedundantAssignEliminator::operator()(FunctionDefinition const& _functionDe for (auto const& retParam: _functionDefinition.returnVariables) m_returnVariables.insert(retParam.name); - RedundantStoreBase::operator()(_functionDefinition); + UnusedStoreBase::operator()(_functionDefinition); } -void RedundantAssignEliminator::operator()(Leave const&) +void UnusedAssignEliminator::operator()(Leave const&) { for (YulString name: m_returnVariables) changeUndecidedTo(name, State::Used); } -void RedundantAssignEliminator::operator()(Block const& _block) +void UnusedAssignEliminator::operator()(Block const& _block) { ScopedSaveAndRestore outerDeclaredVariables(m_declaredVariables, {}); - RedundantStoreBase::operator()(_block); + UnusedStoreBase::operator()(_block); for (auto const& var: m_declaredVariables) finalize(var, State::Unused); } -void RedundantAssignEliminator::visit(Statement const& _statement) +void UnusedAssignEliminator::visit(Statement const& _statement) { - RedundantStoreBase::visit(_statement); + UnusedStoreBase::visit(_statement); if (auto const* assignment = get_if(&_statement)) if (assignment->variableNames.size() == 1) @@ -99,7 +99,7 @@ void RedundantAssignEliminator::visit(Statement const& _statement) m_stores[assignment->variableNames.front().name][&_statement]; } -void RedundantAssignEliminator::shortcutNestedLoop(TrackedStores const& _zeroRuns) +void UnusedAssignEliminator::shortcutNestedLoop(TrackedStores const& _zeroRuns) { // Shortcut to avoid horrible runtime: // Change all assignments that were newly introduced in the for loop to "used". @@ -116,7 +116,7 @@ void RedundantAssignEliminator::shortcutNestedLoop(TrackedStores const& _zeroRun } } -void RedundantAssignEliminator::finalizeFunctionDefinition(FunctionDefinition const& _functionDefinition) +void UnusedAssignEliminator::finalizeFunctionDefinition(FunctionDefinition const& _functionDefinition) { for (auto const& param: _functionDefinition.parameters) finalize(param.name, State::Unused); @@ -124,14 +124,14 @@ void RedundantAssignEliminator::finalizeFunctionDefinition(FunctionDefinition co finalize(retParam.name, State::Used); } -void RedundantAssignEliminator::changeUndecidedTo(YulString _variable, RedundantAssignEliminator::State _newState) +void UnusedAssignEliminator::changeUndecidedTo(YulString _variable, UnusedAssignEliminator::State _newState) { for (auto& assignment: m_stores[_variable]) if (assignment.second == State::Undecided) assignment.second = _newState; } -void RedundantAssignEliminator::finalize(YulString _variable, RedundantAssignEliminator::State _finalState) +void UnusedAssignEliminator::finalize(YulString _variable, UnusedAssignEliminator::State _finalState) { std::map stores = std::move(m_stores[_variable]); m_stores.erase(_variable); diff --git a/libyul/optimiser/RedundantAssignEliminator.h b/libyul/optimiser/UnusedAssignEliminator.h similarity index 94% rename from libyul/optimiser/RedundantAssignEliminator.h rename to libyul/optimiser/UnusedAssignEliminator.h index 65bbb53fa2..b5a2998a17 100644 --- a/libyul/optimiser/RedundantAssignEliminator.h +++ b/libyul/optimiser/UnusedAssignEliminator.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -107,13 +107,13 @@ struct Dialect; * * Prerequisite: Disambiguator, ForLoopInitRewriter. */ -class RedundantAssignEliminator: public RedundantStoreBase +class UnusedAssignEliminator: public UnusedStoreBase { public: - static constexpr char const* name{"RedundantAssignEliminator"}; + static constexpr char const* name{"UnusedAssignEliminator"}; static void run(OptimiserStepContext&, Block& _ast); - explicit RedundantAssignEliminator(Dialect const& _dialect): RedundantStoreBase(_dialect) {} + explicit UnusedAssignEliminator(Dialect const& _dialect): UnusedStoreBase(_dialect) {} void operator()(Identifier const& _identifier) override; void operator()(VariableDeclaration const& _variableDeclaration) override; @@ -122,7 +122,7 @@ class RedundantAssignEliminator: public RedundantStoreBase void operator()(Leave const&) override; void operator()(Block const& _block) override; - using RedundantStoreBase::visit; + using UnusedStoreBase::visit; void visit(Statement const& _statement) override; private: diff --git a/libyul/optimiser/RedundantStoreBase.cpp b/libyul/optimiser/UnusedStoreBase.cpp similarity index 86% rename from libyul/optimiser/RedundantStoreBase.cpp rename to libyul/optimiser/UnusedStoreBase.cpp index 6fc0570b74..27700bdf74 100644 --- a/libyul/optimiser/RedundantStoreBase.cpp +++ b/libyul/optimiser/UnusedStoreBase.cpp @@ -16,10 +16,10 @@ */ // SPDX-License-Identifier: GPL-3.0 /** - * Base class for both RedundantAssignEliminator and RedundantStoreEliminator. + * Base class for both UnusedAssignEliminator and UnusedStoreEliminator. */ -#include +#include #include #include @@ -33,7 +33,7 @@ using namespace std; using namespace solidity; using namespace solidity::yul; -void RedundantStoreBase::operator()(If const& _if) +void UnusedStoreBase::operator()(If const& _if) { visit(*_if.condition); @@ -43,7 +43,7 @@ void RedundantStoreBase::operator()(If const& _if) merge(m_stores, move(skipBranch)); } -void RedundantStoreBase::operator()(Switch const& _switch) +void UnusedStoreBase::operator()(Switch const& _switch) { visit(*_switch.expression); @@ -69,7 +69,7 @@ void RedundantStoreBase::operator()(Switch const& _switch) merge(m_stores, move(branch)); } -void RedundantStoreBase::operator()(FunctionDefinition const& _functionDefinition) +void UnusedStoreBase::operator()(FunctionDefinition const& _functionDefinition) { ScopedSaveAndRestore outerAssignments(m_stores, {}); ScopedSaveAndRestore forLoopInfo(m_forLoopInfo, {}); @@ -79,7 +79,7 @@ void RedundantStoreBase::operator()(FunctionDefinition const& _functionDefinitio finalizeFunctionDefinition(_functionDefinition); } -void RedundantStoreBase::operator()(ForLoop const& _forLoop) +void UnusedStoreBase::operator()(ForLoop const& _forLoop) { ScopedSaveAndRestore outerForLoopInfo(m_forLoopInfo, {}); ScopedSaveAndRestore forLoopNestingDepth(m_forLoopNestingDepth, m_forLoopNestingDepth + 1); @@ -127,19 +127,19 @@ void RedundantStoreBase::operator()(ForLoop const& _forLoop) m_forLoopInfo.pendingBreakStmts.clear(); } -void RedundantStoreBase::operator()(Break const&) +void UnusedStoreBase::operator()(Break const&) { m_forLoopInfo.pendingBreakStmts.emplace_back(move(m_stores)); m_stores.clear(); } -void RedundantStoreBase::operator()(Continue const&) +void UnusedStoreBase::operator()(Continue const&) { m_forLoopInfo.pendingContinueStmts.emplace_back(move(m_stores)); m_stores.clear(); } -void RedundantStoreBase::merge(TrackedStores& _target, TrackedStores&& _other) +void UnusedStoreBase::merge(TrackedStores& _target, TrackedStores&& _other) { util::joinMap(_target, move(_other), []( map& _assignmentHere, @@ -150,7 +150,7 @@ void RedundantStoreBase::merge(TrackedStores& _target, TrackedStores&& _other) }); } -void RedundantStoreBase::merge(TrackedStores& _target, vector&& _source) +void UnusedStoreBase::merge(TrackedStores& _target, vector&& _source) { for (TrackedStores& ts: _source) merge(_target, move(ts)); diff --git a/libyul/optimiser/RedundantStoreBase.h b/libyul/optimiser/UnusedStoreBase.h similarity index 92% rename from libyul/optimiser/RedundantStoreBase.h rename to libyul/optimiser/UnusedStoreBase.h index ed588927c1..a65af4e45a 100644 --- a/libyul/optimiser/RedundantStoreBase.h +++ b/libyul/optimiser/UnusedStoreBase.h @@ -16,7 +16,7 @@ */ // SPDX-License-Identifier: GPL-3.0 /** - * Base class for both RedundantAssignEliminator and RedundantStoreEliminator. + * Base class for both UnusedAssignEliminator and UnusedStoreEliminator. */ #pragma once @@ -34,14 +34,14 @@ namespace solidity::yul struct Dialect; /** - * Base class for both RedundantAssignEliminator and RedundantStoreEliminator. + * Base class for both UnusedAssignEliminator and UnusedStoreEliminator. * * Prerequisite: Disambiguator, ForLoopInitRewriter. */ -class RedundantStoreBase: public ASTWalker +class UnusedStoreBase: public ASTWalker { public: - explicit RedundantStoreBase(Dialect const& _dialect): m_dialect(_dialect) {} + explicit UnusedStoreBase(Dialect const& _dialect): m_dialect(_dialect) {} using ASTWalker::operator(); void operator()(If const& _if) override; diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp index 962cb18a40..cc315c4b97 100644 --- a/test/libyul/YulOptimizerTestCommon.cpp +++ b/test/libyul/YulOptimizerTestCommon.cpp @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include #include #include @@ -231,16 +231,16 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( ForLoopInitRewriter::run(*m_context, *m_ast); SSATransform::run(*m_context, *m_ast); }}, - {"redundantAssignEliminator", [&]() { + {"unusedAssignEliminator", [&]() { disambiguate(); ForLoopInitRewriter::run(*m_context, *m_ast); - RedundantAssignEliminator::run(*m_context, *m_ast); + UnusedAssignEliminator::run(*m_context, *m_ast); }}, {"ssaPlusCleanup", [&]() { disambiguate(); ForLoopInitRewriter::run(*m_context, *m_ast); SSATransform::run(*m_context, *m_ast); - RedundantAssignEliminator::run(*m_context, *m_ast); + UnusedAssignEliminator::run(*m_context, *m_ast); }}, {"loadResolver", [&]() { disambiguate(); @@ -293,7 +293,7 @@ YulOptimizerTestCommon::YulOptimizerTestCommon( ForLoopInitRewriter::run(*m_context, *m_ast); // apply SSA SSATransform::run(*m_context, *m_ast); - RedundantAssignEliminator::run(*m_context, *m_ast); + UnusedAssignEliminator::run(*m_context, *m_ast); // reverse SSA SSAReverser::run(*m_context, *m_ast); FunctionHoister::run(*m_context, *m_ast); diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_branch.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_branch.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_branch.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_branch.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_break.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_break.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_break.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_break.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_continue.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_continue.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_continue_2.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_2.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_continue_2.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_2.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_continue_3.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_3.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_continue_3.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_3.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_decl_inside_break_continue.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_decl_inside_break_continue.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_decl_inside_break_continue.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_decl_inside_break_continue.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_deep_noremove.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_noremove.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_deep_noremove.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_noremove.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_deep_simple.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_simple.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_deep_simple.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_simple.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_multi_break.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_multi_break.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_multi_break.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_multi_break.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_nested.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_nested.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_nested.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_nested.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_rerun.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_rerun.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_rerun.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_rerun.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/for_stmnts_after_break_continue.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_stmnts_after_break_continue.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/for_stmnts_after_break_continue.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/for_stmnts_after_break_continue.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/function.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/function.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/function.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/function.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/if.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/if.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/if.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/if.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/if_overwrite_all_branches.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/if_overwrite_all_branches.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/if_overwrite_all_branches.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/if_overwrite_all_branches.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/if_used_in_one_branch.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/if_used_in_one_branch.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/if_used_in_one_branch.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/if_used_in_one_branch.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/leave.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/leave.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/leave.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/leave.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/multi_assign.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/multi_assign.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/multi_assign.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/multi_assign.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/multivar.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/multivar.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/multivar.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/multivar.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/non_movable.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/non_movable.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/non_movable.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/non_movable.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_break.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_break.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_break.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_break.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_continue.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_continue.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_continue.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_continue.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/scopes.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/scopes.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/scopes.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/scopes.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/simple.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/simple.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/simple.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/simple.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/switch_overwrite_in_all.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_all.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/switch_overwrite_in_all.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_all.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/switch_overwrite_in_one.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_one.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/switch_overwrite_in_one.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_one.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/switch_overwrite_use_combination.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_use_combination.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/switch_overwrite_use_combination.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_use_combination.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/switch_unused.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_unused.yul similarity index 100% rename from test/libyul/yulOptimizerTests/redundantAssignEliminator/switch_unused.yul rename to test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_unused.yul diff --git a/test/yulPhaser/Chromosome.cpp b/test/yulPhaser/Chromosome.cpp index 55bfd8f24b..9a396283d2 100644 --- a/test/yulPhaser/Chromosome.cpp +++ b/test/yulPhaser/Chromosome.cpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include @@ -50,7 +50,7 @@ namespace solidity::phaser::test vector const ChrOmOsoMeSteps{ ConditionalSimplifier::name, FunctionHoister::name, - RedundantAssignEliminator::name, + UnusedAssignEliminator::name, ForLoopConditionOutOfBody::name, Rematerialiser::name, ForLoopConditionOutOfBody::name, From 3b98bee29adcac26e68c72fc4b5f59b43da08f68 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 23 Nov 2021 14:05:14 +0100 Subject: [PATCH 0135/1748] Update z3 version. --- scripts/deps-ppa/static_z3.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deps-ppa/static_z3.sh b/scripts/deps-ppa/static_z3.sh index 66fbd3fa73..e8dec0faee 100755 --- a/scripts/deps-ppa/static_z3.sh +++ b/scripts/deps-ppa/static_z3.sh @@ -25,7 +25,7 @@ set -ev keyid=70D110489D66E2F6 email=builds@ethereum.org packagename=z3-static -version=4.8.12 +version=4.8.13 DISTRIBUTIONS="focal groovy hirsute" From 0e7a065a782b50b95bcca0291e1caefab6ac05bb Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 23 Nov 2021 10:42:18 +0100 Subject: [PATCH 0136/1748] Enhance documentation. --- libyul/optimiser/UnusedStoreBase.h | 5 +++++ test/libyul/yulOptimizerTests/unusedAssignEliminator/for.yul | 2 +- .../yulOptimizerTests/unusedAssignEliminator/for_branch.yul | 2 +- .../yulOptimizerTests/unusedAssignEliminator/for_break.yul | 2 +- .../unusedAssignEliminator/for_continue.yul | 2 +- .../unusedAssignEliminator/for_continue_2.yul | 2 +- .../unusedAssignEliminator/for_continue_3.yul | 2 +- .../for_decl_inside_break_continue.yul | 2 +- .../unusedAssignEliminator/for_deep_noremove.yul | 2 +- .../unusedAssignEliminator/for_deep_simple.yul | 2 +- .../unusedAssignEliminator/for_multi_break.yul | 2 +- .../yulOptimizerTests/unusedAssignEliminator/for_nested.yul | 2 +- .../yulOptimizerTests/unusedAssignEliminator/for_rerun.yul | 2 +- .../for_stmnts_after_break_continue.yul | 2 +- .../yulOptimizerTests/unusedAssignEliminator/function.yul | 2 +- test/libyul/yulOptimizerTests/unusedAssignEliminator/if.yul | 2 +- .../unusedAssignEliminator/if_overwrite_all_branches.yul | 2 +- .../unusedAssignEliminator/if_used_in_one_branch.yul | 2 +- .../yulOptimizerTests/unusedAssignEliminator/leave.yul | 2 +- .../unusedAssignEliminator/multi_assign.yul | 2 +- .../yulOptimizerTests/unusedAssignEliminator/multivar.yul | 2 +- .../yulOptimizerTests/unusedAssignEliminator/non_movable.yul | 2 +- .../unusedAssignEliminator/remove_break.yul | 2 +- .../unusedAssignEliminator/remove_continue.yul | 2 +- .../yulOptimizerTests/unusedAssignEliminator/scopes.yul | 2 +- .../yulOptimizerTests/unusedAssignEliminator/simple.yul | 2 +- .../unusedAssignEliminator/switch_overwrite_in_all.yul | 2 +- .../unusedAssignEliminator/switch_overwrite_in_one.yul | 2 +- .../switch_overwrite_use_combination.yul | 2 +- .../unusedAssignEliminator/switch_unused.yul | 2 +- test/yulPhaser/Chromosome.cpp | 2 +- 31 files changed, 35 insertions(+), 30 deletions(-) diff --git a/libyul/optimiser/UnusedStoreBase.h b/libyul/optimiser/UnusedStoreBase.h index a65af4e45a..3bd4e42976 100644 --- a/libyul/optimiser/UnusedStoreBase.h +++ b/libyul/optimiser/UnusedStoreBase.h @@ -36,6 +36,11 @@ struct Dialect; /** * Base class for both UnusedAssignEliminator and UnusedStoreEliminator. * + * The class tracks the state of abstract "stores" (assignments or mstore/sstore + * statements) across the control-flow. It is the job of the derived class to create + * the stores and track references, but the base class adjusts their "used state" at + * control-flow splits and joins. + * * Prerequisite: Disambiguator, ForLoopInitRewriter. */ class UnusedStoreBase: public ASTWalker diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for.yul index 3149633680..89de8920cd 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for.yul @@ -8,7 +8,7 @@ } } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let a := 2 diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_branch.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_branch.yul index 120b43ce81..8700c8d28b 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_branch.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_branch.yul @@ -14,7 +14,7 @@ mstore(x, 0) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_break.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_break.yul index 1b795ad8c7..db55bf7588 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_break.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_break.yul @@ -13,7 +13,7 @@ mstore(x, 0x42) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue.yul index 0ee9c551da..d3cfb0d84b 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue.yul @@ -16,7 +16,7 @@ x := 3 } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_2.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_2.yul index ee747ae5d0..2d5bae46e2 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_2.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_2.yul @@ -13,7 +13,7 @@ mstore(x, 0x42) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_3.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_3.yul index b70f35d2bc..d9980d376d 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_3.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_continue_3.yul @@ -12,7 +12,7 @@ } } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_decl_inside_break_continue.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_decl_inside_break_continue.yul index f54b21af8b..94b100e2a9 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_decl_inside_break_continue.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_decl_inside_break_continue.yul @@ -19,7 +19,7 @@ mstore(x, 0x42) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x := 1 diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_noremove.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_noremove.yul index 5edd71d58b..02a735f9e5 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_noremove.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_noremove.yul @@ -26,7 +26,7 @@ x := 13 } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x := 1 diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_simple.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_simple.yul index 5b086bab8a..039d856d96 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_simple.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_deep_simple.yul @@ -19,7 +19,7 @@ } } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // for { } 1 { } diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_multi_break.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_multi_break.yul index ce084b1ce1..3b18dcc8dc 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_multi_break.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_multi_break.yul @@ -35,7 +35,7 @@ mstore(x, 0x42) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x := 1 diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_nested.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_nested.yul index a83f536668..101101b923 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_nested.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_nested.yul @@ -32,7 +32,7 @@ mstore(x, 0x42) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x := 1 diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_rerun.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_rerun.yul index 5d1e607385..08cf63a52d 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_rerun.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_rerun.yul @@ -11,7 +11,7 @@ x := 3 } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_stmnts_after_break_continue.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_stmnts_after_break_continue.yul index 5e88df9689..1a92d3b841 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_stmnts_after_break_continue.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/for_stmnts_after_break_continue.yul @@ -23,7 +23,7 @@ mstore(x, 0x42) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x := 1 diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/function.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/function.yul index 2a20ca8b69..044a5f418f 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/function.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/function.yul @@ -12,7 +12,7 @@ r := 2 } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let r diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/if.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/if.yul index 2fab04a36f..7c65680ae6 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/if.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/if.yul @@ -10,7 +10,7 @@ mstore(0, d) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let c diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/if_overwrite_all_branches.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/if_overwrite_all_branches.yul index 7585f848a2..860050e59d 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/if_overwrite_all_branches.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/if_overwrite_all_branches.yul @@ -11,7 +11,7 @@ mstore(0, d) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let c diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/if_used_in_one_branch.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/if_used_in_one_branch.yul index 637a32c02a..90643f174c 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/if_used_in_one_branch.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/if_used_in_one_branch.yul @@ -11,7 +11,7 @@ mstore(0, d) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let c diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/leave.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/leave.yul index 1caee198a1..82bf493470 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/leave.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/leave.yul @@ -21,7 +21,7 @@ } } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // function f(a, b) -> x diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/multi_assign.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/multi_assign.yul index f0845680f4..d4b35e7ee1 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/multi_assign.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/multi_assign.yul @@ -9,7 +9,7 @@ y := 4 } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // function f() -> a, b diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/multivar.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/multivar.yul index 2b13ba3c36..d4dda8f902 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/multivar.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/multivar.yul @@ -6,7 +6,7 @@ a := b } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let a := 2 diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/non_movable.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/non_movable.yul index 343c672dea..e131b3549e 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/non_movable.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/non_movable.yul @@ -4,7 +4,7 @@ a := mload(0) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let a diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_break.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_break.yul index 035f66d385..76a536c2f3 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_break.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_break.yul @@ -12,7 +12,7 @@ } } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let i := 0 diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_continue.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_continue.yul index c4f3b3e43f..27083a73c2 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_continue.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/remove_continue.yul @@ -13,7 +13,7 @@ } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let i := 0 diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/scopes.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/scopes.yul index d3c6cb4a6d..bc2d4d80f6 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/scopes.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/scopes.yul @@ -7,7 +7,7 @@ } } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let a diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/simple.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/simple.yul index 12b9ae6b71..326ce29dcd 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/simple.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/simple.yul @@ -4,6 +4,6 @@ a := 2 } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { let a } diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_all.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_all.yul index a39cdedd70..a6b77f8973 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_all.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_all.yul @@ -8,7 +8,7 @@ mstore(x, 0) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_one.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_one.yul index 271bb4864c..9b0a23cd88 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_one.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_in_one.yul @@ -7,7 +7,7 @@ mstore(x, 0) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_use_combination.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_use_combination.yul index 8d38dcc161..611123db36 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_use_combination.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_overwrite_use_combination.yul @@ -8,7 +8,7 @@ mstore(x, 0) } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x diff --git a/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_unused.yul b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_unused.yul index 94de51b889..c15c889919 100644 --- a/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_unused.yul +++ b/test/libyul/yulOptimizerTests/unusedAssignEliminator/switch_unused.yul @@ -6,7 +6,7 @@ case 0 { mstore(0, 1) } } // ---- -// step: redundantAssignEliminator +// step: unusedAssignEliminator // // { // let x diff --git a/test/yulPhaser/Chromosome.cpp b/test/yulPhaser/Chromosome.cpp index 9a396283d2..19616cde0b 100644 --- a/test/yulPhaser/Chromosome.cpp +++ b/test/yulPhaser/Chromosome.cpp @@ -138,7 +138,7 @@ BOOST_AUTO_TEST_CASE(output_operator_should_create_concise_and_unambiguous_strin BOOST_TEST(chromosome.length() == allSteps.size()); BOOST_TEST(chromosome.optimisationSteps() == allSteps); - BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighFTLMRrmVatpud"); + BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighFTLMRmVatrpud"); } BOOST_AUTO_TEST_CASE(optimisationSteps_should_translate_chromosomes_genes_to_optimisation_step_names) From 4e6b5205ac0e7921edd311a9a2053ec5675a3b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 23 Nov 2021 16:40:54 +0100 Subject: [PATCH 0137/1748] CI: Include workflow name instead of hard-coded "nightly" in gitter notifications --- .circleci/config.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 10d0d0116d..b917dd5670 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,8 +48,13 @@ commands: # but it's broken. CircleCI associates runs on develop/breaking with random old PRs. [[ $CIRCLE_BRANCH == develop || $CIRCLE_BRANCH == breaking ]] || { echo "Running on a PR or a feature branch - notification skipped."; exit 0; } - [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ Nightly job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." - [[ "<< parameters.event >>" == "success" ]] && message=" ✅ Nightly job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." + # Workflow name is not exposed as an env variable. Has to be queried from the API. + # The name is not critical so if anything fails, use the raw workflow ID as a fallback. + workflow_info=$(curl --silent "https://circleci.com/api/v2/workflow/${CIRCLE_WORKFLOW_ID}") || true + workflow_name=$(echo "$workflow_info" | jq --raw-output .name || echo "$CIRCLE_WORKFLOW_ID") + + [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ [${workflow_name}] Job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." + [[ "<< parameters.event >>" == "success" ]] && message=" ✅ [${workflow_name}] Job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." curl "https://api.gitter.im/v1/rooms/${GITTER_NOTIFY_ROOM_ID}/chatMessages" \ --request POST \ From 00fb719d03cb3495ceee9c63fd4a8df4da986f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 23 Nov 2021 16:41:22 +0100 Subject: [PATCH 0138/1748] CI: Don't use # in gitter notifications --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b917dd5670..dce0553751 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -53,8 +53,8 @@ commands: workflow_info=$(curl --silent "https://circleci.com/api/v2/workflow/${CIRCLE_WORKFLOW_ID}") || true workflow_name=$(echo "$workflow_info" | jq --raw-output .name || echo "$CIRCLE_WORKFLOW_ID") - [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ [${workflow_name}] Job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." - [[ "<< parameters.event >>" == "success" ]] && message=" ✅ [${workflow_name}] Job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see [build #${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." + [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ [${workflow_name}] Job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see [build ${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." + [[ "<< parameters.event >>" == "success" ]] && message=" ✅ [${workflow_name}] Job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see [build ${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." curl "https://api.gitter.im/v1/rooms/${GITTER_NOTIFY_ROOM_ID}/chatMessages" \ --request POST \ From 406b1fbcec5bbc0d497adea016d02a98a32ad8e7 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Tue, 23 Nov 2021 18:07:59 +0100 Subject: [PATCH 0139/1748] bump docker hashes and z3 version --- .circleci/config.yml | 16 ++++++++-------- .circleci/osx_install_dependencies.sh | 4 ++-- CMakeLists.txt | 2 +- scripts/build_emscripten.sh | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index dce0553751..fb3abb37af 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,20 +9,20 @@ version: 2.1 parameters: ubuntu-2004-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-8 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:9c3cdfc1d573d1ca3edacd892590a9a83487a1f746a6ca2093d7e009818c5179" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-9 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:3d8a912e8e78e98cd217955d06d98608ad60adc67728d4c3a569991235fa1abb" ubuntu-2004-clang-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004.clang-8 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:61232feea23c8c57e82cf5fae890f8b86bbec353cdc04f2fcba383ca589e1d8b" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004.clang-9 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:a1ba002cae17279d1396a898b04e4e9c45602ad881295db3e2f484a7e24f6f43" ubuntu-1604-clang-ossfuzz-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu1604.clang.ossfuzz-13 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c26a7ffc9fc243a4ec3105b9dc1edcdd964ad0e9665c83172b7ebda74bbf3021" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu1604.clang.ossfuzz-14 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:f353823cce2f6cd2f9f1459d86cd76fdfc551a0261d87626615ea6c1d8f90587" emscripten-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:emscripten-7 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:9ffcd0944433fe100e9433f2aa9ba5c21e096e758ad8a05a4a76feaed3d1f463" + # solbuildpackpusher/solidity-buildpack-deps:emscripten-8 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:842d6074e0e7e5355c89122c1cafc1fdb59696596750e7d56e5f35c0d883ad59" evm-version: type: string default: london diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index 7ef8635a87..a973988a6e 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -61,8 +61,8 @@ then ./scripts/install_obsolete_jsoncpp_1_7_4.sh # z3 - z3_version="4.8.12" - z3_dir="z3-${z3_version}-x64-osx-10.15.7" + z3_version="4.8.13" + z3_dir="z3-${z3_version}-x64-osx-10.16" z3_package="${z3_dir}.zip" wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_package}" validate_checksum "$z3_package" a1f6ef3c99456147c4d3f2652dc6bc90951c4ab3fe7741a255eb794f0ab8938c diff --git a/CMakeLists.txt b/CMakeLists.txt index e3dc030c13..b4e91f8261 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,7 +65,7 @@ configure_file("${CMAKE_SOURCE_DIR}/cmake/templates/license.h.in" include/licens include(EthOptions) configure_project(TESTS) -set(LATEST_Z3_VERSION "4.8.12") +set(LATEST_Z3_VERSION "4.8.13") set(MINIMUM_Z3_VERSION "4.8.0") find_package(Z3) if (${Z3_FOUND}) diff --git a/scripts/build_emscripten.sh b/scripts/build_emscripten.sh index 7b8510026c..f6c9151ebf 100755 --- a/scripts/build_emscripten.sh +++ b/scripts/build_emscripten.sh @@ -34,7 +34,7 @@ else BUILD_DIR="$1" fi -# solbuildpackpusher/solidity-buildpack-deps:emscripten-7 +# solbuildpackpusher/solidity-buildpack-deps:emscripten-8 docker run -v "$(pwd):/root/project" -w /root/project \ - solbuildpackpusher/solidity-buildpack-deps@sha256:9ffcd0944433fe100e9433f2aa9ba5c21e096e758ad8a05a4a76feaed3d1f463 \ + solbuildpackpusher/solidity-buildpack-deps@sha256:842d6074e0e7e5355c89122c1cafc1fdb59696596750e7d56e5f35c0d883ad59 \ ./scripts/ci/build_emscripten.sh "$BUILD_DIR" From ff5c842d673b311a6dba7466f0506680dd3bab63 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Tue, 23 Nov 2021 18:08:36 +0100 Subject: [PATCH 0140/1748] update smtchecker tests --- .../smtCheckerTests/abi/abi_decode_array.sol | 12 +++--------- .../abi/abi_encode_with_sig_hash.sol | 4 +--- .../length_same_after_assignment_3_fail.sol | 2 +- .../array_members/push_as_lhs_1d.sol | 2 +- .../array_members/push_as_lhs_and_rhs_1d.sol | 2 +- .../push_overflow_2_safe_no_overflow_assumption.sol | 1 - .../array_members/push_push_no_args_2_fail.sol | 4 ++-- .../blockchain_state/balance_receive_4.sol | 2 +- .../blockchain_state/balance_receive_ext_calls.sol | 2 +- .../balance_receive_ext_calls_2.sol | 2 +- .../balance_receive_ext_calls_mutex.sol | 2 +- .../blockchain_state/balance_spend.sol | 2 +- .../blockchain_state/balance_spend_2.sol | 1 - .../this_does_not_change_external_call.sol | 2 +- .../branches_in_modifiers_2.sol | 2 +- .../crypto/crypto_functions_compare_hashes.sol | 12 +++++++++--- .../crypto/crypto_functions_not_same.sol | 4 +++- ..._functions_same_input_over_state_same_output.sol | 13 ++++++++++++- .../smtCheckerTests/external_calls/call_mutex.sol | 2 +- .../external_calls/call_reentrancy_view.sol | 2 +- .../smtCheckerTests/external_calls/call_safe.sol | 2 +- .../external_calls/call_with_value_1.sol | 4 +--- .../external_call_this_with_value_1.sol | 2 +- .../external_hash_known_code_state.sol | 2 +- .../external_hash_known_code_state_reentrancy_3.sol | 2 +- ...rnal_hash_known_code_state_reentrancy_unsafe.sol | 4 +--- .../external_calls/external_reentrancy_1.sol | 4 +++- .../external_calls/external_reentrancy_crypto.sol | 3 +++ .../external_calls/external_single_inc.sol | 2 +- .../functions/functions_external_1.sol | 2 +- .../functions/functions_external_2.sol | 2 +- .../smtCheckerTests/functions/getters/struct_3.sol | 11 +++++++++-- .../virtual_function_called_by_constructor.sol | 2 +- .../natspec/unsafe_assert_remains_unsafe.sol | 2 +- .../assignment_module_contract_member_variable.sol | 2 +- .../operators/compound_add_array_index.sol | 2 +- .../operators/compound_bitwise_string_literal_3.sol | 3 ++- .../operators/conditional_assignment_5.sol | 4 +--- .../operators/conditional_assignment_6.sol | 2 +- .../operators/slice_default_start.sol | 3 ++- .../smtCheckerTests/out_of_bounds/array_1.sol | 3 +-- .../overflow/unsigned_mul_overflow.sol | 2 +- .../smtCheckerTests/special/abi_decode_simple.sol | 2 +- .../special/tx_vars_chc_internal.sol | 2 +- .../special/tx_vars_reentrancy_1.sol | 2 +- .../special/tx_vars_reentrancy_2.sol | 2 +- .../try_catch/try_public_var_mapping.sol | 2 +- .../smtCheckerTests/types/abi_type_type_1.sol | 2 +- .../smtCheckerTests/types/address_staticcall.sol | 6 ++++-- .../smtCheckerTests/types/bool_simple_2.sol | 2 +- .../smtCheckerTests/types/fixed_bytes_access_3.sol | 3 +-- .../smtCheckerTests/userTypes/user_abi_1.sol | 2 +- .../smtCheckerTests/userTypes/user_abi_2.sol | 2 +- 53 files changed, 92 insertions(+), 75 deletions(-) diff --git a/test/libsolidity/smtCheckerTests/abi/abi_decode_array.sol b/test/libsolidity/smtCheckerTests/abi/abi_decode_array.sol index 3c88329a35..e2c0894934 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_decode_array.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_decode_array.sol @@ -32,9 +32,6 @@ contract C { // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 1218: (1009-1037): CHC: Error trying to invoke SMT solver. -// Warning 1218: (1056-1084): CHC: Error trying to invoke SMT solver. -// Warning 1218: (1103-1131): CHC: Error trying to invoke SMT solver. // 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. @@ -42,9 +39,6 @@ contract C { // 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 might happen here. -// Warning 6328: (1056-1084): CHC: Assertion violation might happen here. -// Warning 6328: (1103-1131): CHC: Assertion violation might happen here. -// Warning 4661: (1009-1037): BMC: Assertion violation happens here. -// Warning 4661: (1056-1084): BMC: Assertion violation happens here. -// Warning 4661: (1103-1131): BMC: 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. diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_hash.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_hash.sol index dbf4237411..61e755d82d 100644 --- a/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_hash.sol +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_hash.sol @@ -13,9 +13,7 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 1218: (337-375): CHC: Error trying to invoke SMT solver. // Warning 1218: (394-432): CHC: Error trying to invoke SMT solver. -// Warning 6328: (337-375): CHC: Assertion violation might happen here. +// Warning 6328: (337-375): CHC: Assertion violation happens here. // Warning 6328: (394-432): CHC: Assertion violation might happen here. -// Warning 4661: (337-375): BMC: Assertion violation happens here. // Warning 4661: (394-432): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3_fail.sol b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3_fail.sol index 062b668c38..7a7db383b2 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3_fail.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3_fail.sol @@ -31,4 +31,4 @@ contract C { // Warning 6328: (349-375): CHC: Assertion violation happens here.\nCounterexample:\narr = [[], [], [], [], [], [], [], [], []]\nx = 0\ny = 0\nz = 9\nt = 0\n\nTransaction trace:\nC.constructor()\nState: arr = [[], [], [], [], [], [], [], [], []]\nC.f() // Warning 6328: (379-402): CHC: Assertion violation happens here.\nCounterexample:\narr = [[], [], [], [], [], [], [], [], []]\nx = 0\ny = 0\nz = 9\nt = 0\n\nTransaction trace:\nC.constructor()\nState: arr = [[], [], [], [], [], [], [], [], []]\nC.f() // Warning 6328: (406-432): CHC: Assertion violation happens here.\nCounterexample:\narr = [[], [], [], [], [], [], [], [], []]\nx = 0\ny = 0\nz = 9\nt = 0\n\nTransaction trace:\nC.constructor()\nState: arr = [[], [], [], [], [], [], [], [], []]\nC.f() -// Info 1180: Contract invariant(s) for :C:\n!(arr.length <= 3)\n!(arr.length <= 5)\n!(arr.length <= 7)\n!(arr.length <= 8)\n +// Info 1180: Contract invariant(s) for :C:\n!(arr.length <= 7)\n!(arr.length <= 8)\n diff --git a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol index 30f194eb7c..5920a4e747 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol @@ -18,4 +18,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (199-229): CHC: Assertion violation happens here. +// Warning 6328: (199-229): CHC: Assertion violation happens here.\nCounterexample:\nb = [1]\n\nTransaction trace:\nC.constructor()\nState: b = []\nC.g() diff --git a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_1d.sol b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_1d.sol index ad3ba78234..66776ed49f 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_1d.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_1d.sol @@ -14,4 +14,4 @@ contract C { // SMTEngine: all // SMTIgnoreOS: macos // ---- -// Warning 6328: (204-230): CHC: Assertion violation happens here.\nCounterexample:\nb = [0, 0]\nlength = 2\n\nTransaction trace:\nC.constructor()\nState: b = []\nC.f() +// Warning 6328: (204-230): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/array_members/push_overflow_2_safe_no_overflow_assumption.sol b/test/libsolidity/smtCheckerTests/array_members/push_overflow_2_safe_no_overflow_assumption.sol index 60b11c91a6..046cf59a13 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_overflow_2_safe_no_overflow_assumption.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_overflow_2_safe_no_overflow_assumption.sol @@ -13,4 +13,3 @@ contract C { // SMTEngine: all // SMTIgnoreOS: macos // ---- -// Info 1180: Contract invariant(s) for :C:\n(x.length >= 0)\n diff --git a/test/libsolidity/smtCheckerTests/array_members/push_push_no_args_2_fail.sol b/test/libsolidity/smtCheckerTests/array_members/push_push_no_args_2_fail.sol index dcda253ce4..42313dee93 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_push_no_args_2_fail.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_push_no_args_2_fail.sol @@ -13,5 +13,5 @@ contract C { // SMTIgnoreOS: macos // ---- // Warning 6328: (90-116): CHC: Assertion violation happens here.\nCounterexample:\narray2d = [[[0]]]\nlast = 0\n\nTransaction trace:\nC.constructor()\nState: array2d = []\nC.l() -// Warning 6328: (170-186): CHC: Assertion violation happens here. -// Warning 6328: (190-246): CHC: Assertion violation happens here. +// Warning 6328: (170-186): CHC: Assertion violation happens here.\nCounterexample:\narray2d = [[[0]]]\nlast = 1\n\nTransaction trace:\nC.constructor()\nState: array2d = []\nC.l() +// Warning 6328: (190-246): CHC: Assertion violation happens here.\nCounterexample:\narray2d = [[[0]]]\nlast = 1\n\nTransaction trace:\nC.constructor()\nState: array2d = []\nC.l() diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol index e8f750d07a..3e3e564317 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol @@ -15,7 +15,7 @@ contract C { // Warning 4984: (82-85): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. // Warning 4984: (154-160): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. // Warning 4984: (212-218): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. -// Warning 6328: (180-219): CHC: Assertion violation happens here. +// Warning 6328: (180-219): CHC: Assertion violation happens here.\nCounterexample:\nc = 1\n\nTransaction trace:\nC.constructor()\nState: c = 0\nC.f(){ msg.value: 11 }\nState: c = 1\nC.inv() // Info 1180: Contract invariant(s) for :C:\n(((11 * c) + ((- 1) * (:var 1).balances[address(this)])) <= 0)\n // Warning 2661: (82-85): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. // Warning 2661: (154-160): BMC: Overflow (resulting value larger than 2**256 - 1) happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol index e46dfda34b..1ee90e41d0 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol @@ -15,5 +15,5 @@ contract C { // ---- // Warning 1218: (131-165): CHC: Error trying to invoke SMT solver. // Warning 6328: (131-165): CHC: Assertion violation might happen here. -// Info 1180: Reentrancy property(ies) for :C:\n(!( >= 2) && (((:var 0).balances[address(this)] + ((- 1) * (:var 1).balances[address(this)])) >= 0))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this).balance == x)\n = 2 -> Assertion failed at assert(address(this).balance >= x)\n +// Info 1180: Reentrancy property(ies) for :C:\n(!( >= 2) && (((:var 1).balances[address(this)] + ((- 1) * (:var 0).balances[address(this)])) <= 0))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this).balance == x)\n = 2 -> Assertion failed at assert(address(this).balance >= x)\n // Warning 4661: (131-165): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_2.sol index 28c4734bd4..c53f156d63 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_2.sol @@ -12,4 +12,4 @@ contract C { // ---- // Warning 9302: (82-93): Return value of low-level calls not used. // Warning 6328: (97-131): CHC: Assertion violation happens here. -// Info 1180: Reentrancy property(ies) for :C:\n((((:var 1).balances[address(this)] + ((- 1) * (:var 0).balances[address(this)])) <= 0) && !( >= 2))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this).balance == x)\n = 2 -> Assertion failed at assert(address(this).balance >= x)\n +// Info 1180: Reentrancy property(ies) for :C:\n(!( >= 2) && (((:var 1).balances[address(this)] + ((- 1) * (:var 0).balances[address(this)])) <= 0))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this).balance == x)\n = 2 -> Assertion failed at assert(address(this).balance >= x)\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_mutex.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_mutex.sol index 559f67e193..76443dfd05 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_mutex.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_mutex.sol @@ -22,4 +22,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (277-310): CHC: Assertion violation happens here. -// Info 1180: Reentrancy property(ies) for :C:\n((!lock || (((:var 3).balances[address(this)] + ((- 1) * (:var 1).balances[address(this)])) <= 0)) && !( = 1) && (lock' || !lock) && (!lock || (((:var 3).balances[address(this)] + ((- 1) * (:var 1).balances[address(this)])) >= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this).balance == x)\n = 2 -> Assertion failed at assert(address(this).balance < x)\n +// Info 1180: Reentrancy property(ies) for :C:\n((lock' || !lock) && !( = 1) && (!lock || (((:var 3).balances[address(this)] + ((- 1) * (:var 1).balances[address(this)])) >= 0)) && (!lock || (((:var 3).balances[address(this)] + ((- 1) * (:var 1).balances[address(this)])) <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this).balance == x)\n = 2 -> Assertion failed at assert(address(this).balance < x)\n diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol index 1e4ec7a32a..bd30b77d1f 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol @@ -19,5 +19,5 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (280-314): CHC: Assertion violation happens here. -// Info 1180: Contract invariant(s) for :C:\n((!(c <= 1) || !((:var 1).balances[address(this)] <= 91)) && !((:var 1).balances[address(this)] <= 82) && (!(c <= 0) || !((:var 1).balances[address(this)] <= 100)))\n +// Info 1180: Contract invariant(s) for :C:\n((!(c <= 1) || !((:var 1).balances[address(this)] <= 90)) && !((:var 1).balances[address(this)] <= 81) && (!(c <= 0) || !((:var 1).balances[address(this)] <= 100)))\n // Warning 1236: (175-190): BMC: Insufficient funds happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend_2.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend_2.sol index 0b3a432e8c..5df0b99956 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend_2.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_spend_2.sol @@ -16,7 +16,6 @@ contract C { // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 1218: (193-226): CHC: Error trying to invoke SMT solver. // Warning 6328: (193-226): CHC: Assertion violation might happen here. // Warning 6328: (245-279): CHC: Assertion violation happens here. // Warning 6328: (298-332): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_external_call.sol b/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_external_call.sol index 0b5136dcab..f169645010 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_external_call.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_external_call.sol @@ -18,4 +18,4 @@ contract C { // SMTEngine: all // SMTIgnoreOS: macos // ---- -// Info 1180: Contract invariant(s) for :C:\n(((address(this) + ((- 1) * t)) <= 0) && ((address(this) + ((- 1) * t)) >= 0))\nReentrancy property(ies) for :C:\n((!( >= 2) || !((t + ((- 1) * address(this))) = 0)) && (!((t + ((- 1) * address(this))) <= 0) || ((t' + ((- 1) * address(this))) <= 0)) && (!((t + ((- 1) * address(this))) >= 0) || ((address(this) + ((- 1) * t')) <= 0)))\n((( <= 0) || !((t + ((- 1) * address(this))) = 0)) && (!((t + ((- 1) * address(this))) <= 0) || ((t' + ((- 1) * address(this))) <= 0)) && (!((t + ((- 1) * address(this))) >= 0) || ((address(this) + ((- 1) * t')) <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this) == t)\n = 2 -> Assertion failed at assert(a == t)\n +// Info 1180: Contract invariant(s) for :C:\n(((address(this) + ((- 1) * t)) <= 0) && ((address(this) + ((- 1) * t)) >= 0))\nReentrancy property(ies) for :C:\n((!((t + ((- 1) * address(this))) = 0) || ( <= 0)) && (!((t + ((- 1) * address(this))) <= 0) || ((t' + ((- 1) * address(this))) <= 0)) && (!((t + ((- 1) * address(this))) >= 0) || ((address(this) + ((- 1) * t')) <= 0)))\n((!( >= 2) || !((t + ((- 1) * address(this))) = 0)) && (!((t + ((- 1) * address(this))) <= 0) || ((t' + ((- 1) * address(this))) <= 0)) && (!((t + ((- 1) * address(this))) >= 0) || ((address(this) + ((- 1) * t')) <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(address(this) == t)\n = 2 -> Assertion failed at assert(a == t)\n diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol index 9765fc1f91..4241fa9e29 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol @@ -44,5 +44,5 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (255-269): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.test()\n C.reset_if_overflow() -- internal call -// Warning 6328: (502-519): CHC: Assertion violation happens here. +// Warning 6328: (502-519): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\noldx = 1\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.set(1)\nState: x = 1\nC.test()\n C.reset_if_overflow() -- internal call // Warning 6328: (615-629): CHC: Assertion violation happens here.\nCounterexample:\nx = 1\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.set(10)\nState: x = 10\nC.test()\n C.reset_if_overflow() -- internal call diff --git a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_compare_hashes.sol b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_compare_hashes.sol index a49aeac090..79b30a1239 100644 --- a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_compare_hashes.sol +++ b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_compare_hashes.sol @@ -12,6 +12,12 @@ contract C { // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 6328: (150-164): CHC: Assertion violation happens here. -// Warning 6328: (168-182): CHC: Assertion violation happens here. -// Warning 6328: (186-200): CHC: Assertion violation happens here. +// Warning 1218: (150-164): CHC: Error trying to invoke SMT solver. +// Warning 1218: (168-182): CHC: Error trying to invoke SMT solver. +// Warning 1218: (186-200): CHC: Error trying to invoke SMT solver. +// Warning 6328: (150-164): CHC: Assertion violation might happen here. +// Warning 6328: (168-182): CHC: Assertion violation might happen here. +// Warning 6328: (186-200): CHC: Assertion violation might happen here. +// Warning 4661: (150-164): BMC: Assertion violation happens here. +// Warning 4661: (168-182): BMC: Assertion violation happens here. +// Warning 4661: (186-200): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_not_same.sol b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_not_same.sol index a8c6199d0f..59a011f240 100644 --- a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_not_same.sol +++ b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_not_same.sol @@ -12,4 +12,6 @@ contract C { // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 6328: (196-210): CHC: Assertion violation happens here. +// Warning 1218: (196-210): CHC: Error trying to invoke SMT solver. +// Warning 6328: (196-210): CHC: Assertion violation might happen here. +// Warning 4661: (196-210): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_over_state_same_output.sol b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_over_state_same_output.sol index 228f9d5809..94eedd5991 100644 --- a/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_over_state_same_output.sol +++ b/test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_over_state_same_output.sol @@ -37,4 +37,15 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1180: Contract invariant(s) for :C:\n(((erc + ((- 1) * ecrecover(tuple_constructor(h, v, r, s)))) <= 0) && ((erc + ((- 1) * ecrecover(tuple_constructor(h, v, r, s)))) >= 0))\n(((kec + ((- 1) * keccak256(data))) >= 0) && ((kec + ((- 1) * keccak256(data))) <= 0))\n(((rip + ((- 1) * ripemd160(data))) <= 0) && ((rip + ((- 1) * ripemd160(data))) >= 0))\n(((sha + ((- 1) * sha256(data))) <= 0) && ((sha + ((- 1) * sha256(data))) >= 0))\n +// Warning 1218: (544-563): CHC: Error trying to invoke SMT solver. +// Warning 1218: (567-586): CHC: Error trying to invoke SMT solver. +// Warning 1218: (590-609): CHC: Error trying to invoke SMT solver. +// Warning 1218: (613-632): CHC: Error trying to invoke SMT solver. +// Warning 6328: (544-563): CHC: Assertion violation might happen here. +// Warning 6328: (567-586): CHC: Assertion violation might happen here. +// Warning 6328: (590-609): CHC: Assertion violation might happen here. +// Warning 6328: (613-632): CHC: Assertion violation might happen here. +// Warning 4661: (544-563): BMC: Assertion violation happens here. +// Warning 4661: (567-586): BMC: Assertion violation happens here. +// Warning 4661: (590-609): BMC: Assertion violation happens here. +// Warning 4661: (613-632): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_mutex.sol b/test/libsolidity/smtCheckerTests/external_calls/call_mutex.sol index a310939246..e85eb00aab 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_mutex.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_mutex.sol @@ -23,4 +23,4 @@ contract C { // SMTEngine: all // ---- // Warning 9302: (218-234): Return value of low-level calls not used. -// Info 1180: Reentrancy property(ies) for :C:\n((!lock || ((x' + ((- 1) * x)) = 0)) && ( <= 0) && (lock' || !lock))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(y == x)\n +// Info 1180: Reentrancy property(ies) for :C:\n((lock' || !lock) && ( <= 0) && (!lock || ((x' + ((- 1) * x)) = 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(y == x)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_reentrancy_view.sol b/test/libsolidity/smtCheckerTests/external_calls/call_reentrancy_view.sol index f0f844fff3..87a9e22614 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_reentrancy_view.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_reentrancy_view.sol @@ -15,4 +15,4 @@ contract C { // Warning 2519: (106-112): This declaration shadows an existing declaration. // Warning 2072: (106-112): Unused local variable. // Warning 2072: (114-131): Unused local variable. -// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n((!(x <= 0) || (x' <= 0)) && (( <= 0) || !(x <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n((!(x <= 0) || (x' <= 0)) && (!(x <= 0) || ( <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol b/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol index 09d3a25922..f4f9d15ad4 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol @@ -10,4 +10,4 @@ contract C { // ---- // Warning 2072: (57-63): Unused local variable. // Warning 2072: (65-82): Unused local variable. -// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n((!(x <= 0) || (x' <= 0)) && (( <= 0) || !(x <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n((!(x <= 0) || ( <= 0)) && (!(x <= 0) || (x' <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n 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 2569802255..f9293f6930 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_with_value_1.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_with_value_1.sol @@ -11,8 +11,6 @@ contract C { // SMTIgnoreOS: macos // ---- // Warning 9302: (96-117): Return value of low-level calls not used. -// Warning 1218: (175-211): CHC: Error trying to invoke SMT solver. // Warning 6328: (121-156): CHC: Assertion violation might happen here. -// Warning 6328: (175-211): CHC: Assertion violation might happen here. +// Warning 6328: (175-211): CHC: Assertion violation happens here.\nCounterexample:\n\ni = 0x0\n\nTransaction trace:\nC.constructor()\nC.g(0x0)\n i.call{value: 10}("") -- untrusted external call // Warning 4661: (121-156): BMC: Assertion violation happens here. -// Warning 4661: (175-211): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_call_this_with_value_1.sol b/test/libsolidity/smtCheckerTests/external_calls/external_call_this_with_value_1.sol index 06390b12ca..c52e0773fb 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_call_this_with_value_1.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_call_this_with_value_1.sol @@ -11,4 +11,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (157-192): CHC: Assertion violation happens here. +// Warning 6328: (157-192): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.g()\n C.h() -- trusted external call diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state.sol index 317400e1d1..2468a1a72d 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state.sol @@ -36,4 +36,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 6328: (495-532): CHC: Assertion violation happens here. -// Info 1180: Reentrancy property(ies) for :C:\n(((owner + ((- 1) * owner')) >= 0) && !( = 1) && ((owner + ((- 1) * owner')) <= 0))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(prevOwner == owner)\n = 3 -> Assertion failed at assert(owner == address(0) || y != z)\n +// Info 1180: Reentrancy property(ies) for :C:\n(((owner + ((- 1) * owner')) <= 0) && !( = 1) && ((owner + ((- 1) * owner')) >= 0))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(prevOwner == owner)\n = 3 -> Assertion failed at assert(owner == address(0) || y != z)\n 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 e5259c6c44..508047c39b 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 @@ -41,4 +41,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Info 1180: Contract invariant(s) for :C:\n((insidef || (z <= 0)) && (y <= 0))\nReentrancy property(ies) for :C:\n((!insidef || !( >= 2)) && (!(y <= 0) || (y' <= 0)) && (insidef' || !insidef))\n((!insidef || !( >= 3)) && (insidef' || !insidef))\n = 0 -> no errors\n = 2 -> Assertion failed at assert(z == y)\n = 3 -> Assertion failed at assert(prevOwner == owner)\n +// Info 1180: Contract invariant(s) for :C:\n((insidef || (z <= 0)) && (y <= 0))\nReentrancy property(ies) for :C:\n((!insidef || !( >= 2)) && (insidef' || !insidef) && (!(y <= 0) || (y' <= 0)))\n((!insidef || !( >= 3)) && (insidef' || !insidef))\n = 0 -> no errors\n = 2 -> Assertion failed at assert(z == y)\n = 3 -> Assertion failed at assert(prevOwner == owner)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe.sol index 32aa483a7d..d871d6e134 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe.sol @@ -35,7 +35,5 @@ contract C { // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 1218: (366-392): CHC: Error trying to invoke SMT solver. // Warning 6328: (348-362): CHC: Assertion violation happens here. -// Warning 6328: (366-392): CHC: Assertion violation might happen here. -// Warning 4661: (366-392): BMC: Assertion violation happens here. +// Warning 6328: (366-392): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_1.sol b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_1.sol index adde1eb61c..5683a5248b 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_1.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_1.sol @@ -16,4 +16,6 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (206-220): CHC: Assertion violation happens here.\nCounterexample:\nlocked = false\ntarget = 0x0\n\nTransaction trace:\nC.constructor()\nState: locked = true\nC.call(0x0)\n D(target).e() -- untrusted external call, synthesized as:\n C.broken() -- reentrant call +// Warning 1218: (206-220): CHC: Error trying to invoke SMT solver. +// Warning 6328: (206-220): CHC: Assertion violation might happen here. +// Warning 4661: (206-220): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol index 2a79e6c4d2..46e8ac1487 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol @@ -27,6 +27,9 @@ contract C { // SMTEngine: all // SMTIgnoreInv: yes // ---- +// Warning 1218: (264-283): CHC: Error trying to invoke SMT solver. // Warning 1218: (302-333): CHC: Error trying to invoke SMT solver. +// Warning 6328: (264-283): CHC: Assertion violation might happen here. // Warning 6328: (302-333): CHC: Assertion violation might happen here. +// Warning 4661: (264-283): BMC: Assertion violation happens here. // Warning 4661: (302-333): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_single_inc.sol b/test/libsolidity/smtCheckerTests/external_calls/external_single_inc.sol index 0b944acb2b..994fbde16f 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_single_inc.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_single_inc.sol @@ -23,4 +23,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (223-240): CHC: Assertion violation happens here. +// Warning 6328: (223-240): CHC: Assertion violation happens here.\nCounterexample:\nx = 1, y = 1, d = 0\noldX = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0, y = 0, d = 0\nC.inc()\nState: x = 0, y = 1, d = 0\nC.f()\n d.d() -- untrusted external call, synthesized as:\n C.inc() -- reentrant call diff --git a/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol b/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol index ace2d56f29..19dd010a5f 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol @@ -18,4 +18,4 @@ contract C // SMTEngine: all // SMTIgnoreOS: macos // ---- -// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n!( = 1)\n((!(x <= 0) || !( >= 2)) && (!(x <= 0) || (x' <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == y)\n = 2 -> Assertion failed at assert(x == y)\n +// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n!( = 1)\n((!( >= 2) || !(x <= 0)) && (!(x <= 0) || (x' <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == y)\n = 2 -> Assertion failed at assert(x == y)\n diff --git a/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol b/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol index 5efcb2da1b..3a3b295e45 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_external_2.sol @@ -25,4 +25,4 @@ contract C // SMTIgnoreOS: macos // ---- // Warning 6328: (234-253): CHC: Assertion violation happens here. -// Info 1180: Reentrancy property(ies) for :C:\n!( = 1)\n((!((map[1] + ((- 1) * map[0])) <= 0) || ((map'[1] + ((- 1) * map'[0])) <= 0)) && !( = 2) && (!((map[1] + ((- 1) * map[0])) >= 0) || ((map'[0] + ((- 1) * map'[1])) <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(map[0] == map[1])\n = 2 -> Assertion failed at assert(map[0] == map[1])\n = 3 -> Assertion failed at assert(map[0] == 0)\n +// Info 1180: Reentrancy property(ies) for :C:\n!( = 1)\n((!((map[1] + ((- 1) * map[0])) >= 0) || ((map'[0] + ((- 1) * map'[1])) <= 0)) && !( = 2) && (!((map[1] + ((- 1) * map[0])) <= 0) || ((map'[1] + ((- 1) * map'[0])) <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(map[0] == map[1])\n = 2 -> Assertion failed at assert(map[0] == map[1])\n = 3 -> Assertion failed at assert(map[0] == 0)\n diff --git a/test/libsolidity/smtCheckerTests/functions/getters/struct_3.sol b/test/libsolidity/smtCheckerTests/functions/getters/struct_3.sol index ea433b7863..b5cdcc32dd 100644 --- a/test/libsolidity/smtCheckerTests/functions/getters/struct_3.sol +++ b/test/libsolidity/smtCheckerTests/functions/getters/struct_3.sol @@ -21,5 +21,12 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (307-326): CHC: Assertion violation happens here. -// Info 1180: Contract invariant(s) for :C:\n!(m.b.length <= 2)\n +// Warning 1218: (273-277): CHC: Error trying to invoke SMT solver. +// Warning 1218: (281-287): CHC: Error trying to invoke SMT solver. +// Warning 1218: (314-318): CHC: Error trying to invoke SMT solver. +// Warning 1218: (307-326): CHC: Error trying to invoke SMT solver. +// Warning 6368: (273-277): CHC: Out of bounds access might happen here. +// Warning 6368: (281-287): CHC: Out of bounds access might happen here. +// Warning 6368: (314-318): CHC: Out of bounds access might happen here. +// Warning 6328: (307-326): CHC: Assertion violation might happen here. +// Warning 4661: (307-326): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/functions/virtual_function_called_by_constructor.sol b/test/libsolidity/smtCheckerTests/functions/virtual_function_called_by_constructor.sol index 0117f9b49d..e30a5e7438 100644 --- a/test/libsolidity/smtCheckerTests/functions/virtual_function_called_by_constructor.sol +++ b/test/libsolidity/smtCheckerTests/functions/virtual_function_called_by_constructor.sol @@ -27,4 +27,4 @@ contract C is A { // ---- // Warning 6328: (199-214): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\n\nTransaction trace:\nA.constructor()\nState: x = 2\nA.i() // Warning 6328: (387-401): CHC: Assertion violation happens here.\nCounterexample:\nx = 10\n\nTransaction trace:\nC.constructor()\nState: x = 10\nC.i() -// Info 1180: Contract invariant(s) for :A:\n(!(x <= 1) && !(x >= 3))\nContract invariant(s) for :C:\n(!(x >= 11) && !(x <= 9))\n +// Info 1180: Contract invariant(s) for :A:\n(!(x <= 1) && !(x >= 3))\nContract invariant(s) for :C:\n(!(x <= 9) && !(x >= 11))\n diff --git a/test/libsolidity/smtCheckerTests/natspec/unsafe_assert_remains_unsafe.sol b/test/libsolidity/smtCheckerTests/natspec/unsafe_assert_remains_unsafe.sol index 1bb6caa423..6202478a69 100644 --- a/test/libsolidity/smtCheckerTests/natspec/unsafe_assert_remains_unsafe.sol +++ b/test/libsolidity/smtCheckerTests/natspec/unsafe_assert_remains_unsafe.sol @@ -24,4 +24,4 @@ contract C { // SMTEngine: chc // ---- // Warning 6328: (74-87): CHC: Assertion violation happens here.\nCounterexample:\nx = 0, y = 0\n_x = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0, y = 0\nC.g(0)\n C.f1(0) -- internal call -// Warning 6328: (117-130): CHC: Assertion violation happens here.\nCounterexample:\nx = 1, y = 0\n_x = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0, y = 0\nC.g(0)\n C.f1(0) -- internal call\n C.f2(0) -- internal call +// Warning 6328: (117-130): CHC: Assertion violation happens here.\nCounterexample:\nx = 0, y = 0\n_x = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0, y = 0\nC.g(0)\n C.f1(0) -- internal call\n C.f2(0) -- internal call 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 e4b7646861..18869ee3a3 100644 --- a/test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol +++ b/test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol @@ -30,4 +30,4 @@ contract A { // ---- // Warning 6328: (AASource:159-178): CHC: Assertion violation happens here.\nCounterexample:\nx = (- 1), y = (- 2)\n\nTransaction trace:\nA.constructor()\nState: x = 0, y = 0\nA.a()\nState: x = (- 2), y = (- 2)\nA.a() // Warning 6328: (AASource:370-386): CHC: Assertion violation happens here.\nCounterexample:\nx = 8, y = (- 2)\n\nTransaction trace:\nA.constructor()\nState: x = 0, y = 0\nA.a() -// Info 1180: Contract invariant(s) for AASource:A:\n(((x = (- 2)) && (y = (- 2))) || ((x = 0) && (y = 0)))\n(((x = 0) && (y = 0)) || ((x = (- 2)) && (y = (- 2))))\n +// Info 1180: Contract invariant(s) for AASource:A:\n(((x = 0) && (y = 0)) || ((x = (- 2)) && (y = (- 2))))\n diff --git a/test/libsolidity/smtCheckerTests/operators/compound_add_array_index.sol b/test/libsolidity/smtCheckerTests/operators/compound_add_array_index.sol index 4068ad2b96..424baf927a 100644 --- a/test/libsolidity/smtCheckerTests/operators/compound_add_array_index.sol +++ b/test/libsolidity/smtCheckerTests/operators/compound_add_array_index.sol @@ -19,4 +19,4 @@ contract C // ==== // SMTEngine: all // ---- -// Warning 6328: (262-284): CHC: Assertion violation happens here.\nCounterexample:\narray = [200, 0]\nx = 0\np = 0\n\nTransaction trace:\nC.constructor()\nState: array = [0, 0]\nC.f(0, 0) +// Warning 6328: (262-284): CHC: Assertion violation happens here.\nCounterexample:\narray = [299, 0]\nx = 99\np = 0\n\nTransaction trace:\nC.constructor()\nState: array = [0, 0]\nC.f(99, 0) diff --git a/test/libsolidity/smtCheckerTests/operators/compound_bitwise_string_literal_3.sol b/test/libsolidity/smtCheckerTests/operators/compound_bitwise_string_literal_3.sol index 3ac248fb22..b2d56cb128 100644 --- a/test/libsolidity/smtCheckerTests/operators/compound_bitwise_string_literal_3.sol +++ b/test/libsolidity/smtCheckerTests/operators/compound_bitwise_string_literal_3.sol @@ -18,4 +18,5 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (229-276): CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0x6062606464666060606260646466606060626064646660606062606464666060\nz = 0x6062606464666060606260646466606060626064646660606062606464666060\n\nTransaction trace:\nC.constructor()\nC.f() -// Warning 6328: (394-437): CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0x63666566676e616263666566676e616263666566676e616263666566676e6162\nz = 0x63666566676e616263666566676e616263666566676e616263666566676e6162\n\nTransaction trace:\nC.constructor()\nC.f() +// Warning 6328: (394-437): CHC: Assertion violation might happen here. +// Warning 4661: (394-437): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol index dd467f8532..24be3cd8ea 100644 --- a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol +++ b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol @@ -25,6 +25,4 @@ contract C { // SMTIgnoreCex: yes // ---- // Warning 2072: (249-255): Unused local variable. -// Warning 1218: (271-295): CHC: Error trying to invoke SMT solver. -// Warning 6328: (271-295): CHC: Assertion violation might happen here. -// Warning 4661: (271-295): BMC: Assertion violation happens here. +// Warning 6328: (271-295): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol index 3b89e1afb2..1affbb6ca0 100644 --- a/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol +++ b/test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol @@ -25,4 +25,4 @@ contract C { // SMTIgnoreOS: macos // ---- // Warning 2072: (255-261): Unused local variable. -// Info 1180: Reentrancy property(ies) for :C:\n((!(x' <= 0) || ((x' + ((- 1) * x)) = 0)) && ( <= 0) && (!(x' >= 3) || ((x' + ((- 1) * x)) = 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 2 || x == 1)\n +// Info 1180: Reentrancy property(ies) for :C:\n((!(x' >= 3) || (a' = a)) && (!(x' <= 0) || !(x >= 2)) && ( <= 0) && (!(x <= 2) || !(x' >= 3)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 2 || x == 1)\n diff --git a/test/libsolidity/smtCheckerTests/operators/slice_default_start.sol b/test/libsolidity/smtCheckerTests/operators/slice_default_start.sol index a4dba47bcd..2dcb635193 100644 --- a/test/libsolidity/smtCheckerTests/operators/slice_default_start.sol +++ b/test/libsolidity/smtCheckerTests/operators/slice_default_start.sol @@ -11,5 +11,6 @@ contract C { // SMTEngine: all // ---- // Warning 6328: (150-182): CHC: Assertion violation might happen here. -// Warning 6328: (186-218): CHC: Assertion violation happens here. +// Warning 6328: (186-218): CHC: Assertion violation might happen here. // Warning 4661: (150-182): BMC: Assertion violation happens here. +// Warning 4661: (186-218): BMC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol b/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol index ee57f069d4..c26e64fccb 100644 --- a/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol +++ b/test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol @@ -21,7 +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.\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() +// Info 1180: Contract invariant(s) for :C:\n((a.length + ((- 1) * l)) <= 0)\n // 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/overflow/unsigned_mul_overflow.sol b/test/libsolidity/smtCheckerTests/overflow/unsigned_mul_overflow.sol index 045fcbff86..0a6d85a7ea 100644 --- a/test/libsolidity/smtCheckerTests/overflow/unsigned_mul_overflow.sol +++ b/test/libsolidity/smtCheckerTests/overflow/unsigned_mul_overflow.sol @@ -6,4 +6,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 4984: (80-85): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\n\nx = 2\ny = 57896044618658097711785492504343953926634992332820282019728792003956564819968\n = 0\n\nTransaction trace:\nC.constructor()\nC.f(2, 57896044618658097711785492504343953926634992332820282019728792003956564819968) +// Warning 4984: (80-85): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\n\nx = 57896044618658097711785492504343953926634992332820282019728792003956564819968\ny = 2\n = 0\n\nTransaction trace:\nC.constructor()\nC.f(57896044618658097711785492504343953926634992332820282019728792003956564819968, 2) diff --git a/test/libsolidity/smtCheckerTests/special/abi_decode_simple.sol b/test/libsolidity/smtCheckerTests/special/abi_decode_simple.sol index 618f762767..a015aba72a 100644 --- a/test/libsolidity/smtCheckerTests/special/abi_decode_simple.sol +++ b/test/libsolidity/smtCheckerTests/special/abi_decode_simple.sol @@ -13,4 +13,4 @@ contract C { // Warning 2072: (82-86): Unused local variable. // Warning 2072: (140-150): Unused local variable. // Warning 2072: (152-156): Unused local variable. -// Warning 6328: (220-236): CHC: Assertion violation happens here.\nCounterexample:\n\na1 = 2437\nb1 = 0x0a\nc1 = 9\na2 = 2437\nb2 = 0x0a\nc2 = 9\n\nTransaction trace:\nC.constructor()\nC.f(data) +// Warning 6328: (220-236): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/special/tx_vars_chc_internal.sol b/test/libsolidity/smtCheckerTests/special/tx_vars_chc_internal.sol index ad958fe958..4c3682c60a 100644 --- a/test/libsolidity/smtCheckerTests/special/tx_vars_chc_internal.sol +++ b/test/libsolidity/smtCheckerTests/special/tx_vars_chc_internal.sol @@ -20,4 +20,4 @@ contract C { // ==== // SMTEngine: chc // ---- -// Warning 6328: (343-377): CHC: Assertion violation happens here.\nCounterexample:\ngas = 0, origin = 0x0\n\nTransaction trace:\nC.constructor()\nState: gas = 0, origin = 0x0\nC.f(){ tx.gasprice: 0, tx.origin: 0x0 }\n C.g() -- internal call +// Warning 6328: (343-377): CHC: Assertion violation happens here.\nCounterexample:\ngas = 0, origin = 0x52f7\n\nTransaction trace:\nC.constructor()\nState: gas = 0, origin = 0x0\nC.f(){ tx.gasprice: 0, tx.origin: 0x52f7 }\n C.g() -- internal call diff --git a/test/libsolidity/smtCheckerTests/special/tx_vars_reentrancy_1.sol b/test/libsolidity/smtCheckerTests/special/tx_vars_reentrancy_1.sol index 50260aa3d2..71608eabd3 100644 --- a/test/libsolidity/smtCheckerTests/special/tx_vars_reentrancy_1.sol +++ b/test/libsolidity/smtCheckerTests/special/tx_vars_reentrancy_1.sol @@ -13,4 +13,4 @@ contract C { // SMTEngine: all // SMTIgnoreOS: macos // ---- -// Warning 6328: (135-169): CHC: Assertion violation happens here.\nCounterexample:\n\n_i = 0\nx = 841\n\nTransaction trace:\nC.constructor()\nC.g(0){ msg.value: 38 }\n _i.f() -- untrusted external call, synthesized as:\n C.g(0){ msg.value: 0 } -- reentrant call\n _i.f() -- untrusted external call +// Warning 6328: (135-169): CHC: Assertion violation happens here.\nCounterexample:\n\n_i = 0\nx = 1236\n\nTransaction trace:\nC.constructor()\nC.g(0){ msg.value: 38 }\n _i.f() -- untrusted external call, synthesized as:\n C.g(0){ msg.value: 1 } -- reentrant call\n _i.f() -- untrusted external call diff --git a/test/libsolidity/smtCheckerTests/special/tx_vars_reentrancy_2.sol b/test/libsolidity/smtCheckerTests/special/tx_vars_reentrancy_2.sol index aaddec5b5a..206d95c466 100644 --- a/test/libsolidity/smtCheckerTests/special/tx_vars_reentrancy_2.sol +++ b/test/libsolidity/smtCheckerTests/special/tx_vars_reentrancy_2.sol @@ -13,4 +13,4 @@ contract C { // SMTEngine: all // SMTIgnoreOS: macos // ---- -// Warning 6328: (157-191): CHC: Assertion violation happens here.\nCounterexample:\n\n_i = 0\nx = 2537\n\nTransaction trace:\nC.constructor()\nC.g(0){ msg.value: 38 }\n _i.f{ value: 100 }() -- untrusted external call +// Warning 6328: (157-191): CHC: Assertion violation happens here.\nCounterexample:\n\n_i = 0\nx = 101\n\nTransaction trace:\nC.constructor()\nC.g(0){ msg.value: 69 }\n _i.f{ value: 100 }() -- untrusted external call diff --git a/test/libsolidity/smtCheckerTests/try_catch/try_public_var_mapping.sol b/test/libsolidity/smtCheckerTests/try_catch/try_public_var_mapping.sol index 0854dedd17..2caae5e164 100644 --- a/test/libsolidity/smtCheckerTests/try_catch/try_public_var_mapping.sol +++ b/test/libsolidity/smtCheckerTests/try_catch/try_public_var_mapping.sol @@ -21,5 +21,5 @@ contract C { // SMTEngine: all // SMTIgnoreOS: macos // ---- -// Warning 6328: (280-300): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.f() +// Warning 6328: (280-300): CHC: Assertion violation happens here. // Info 1180: Contract invariant(s) for :C:\n!(m[0].length <= 1)\n(!(m[0][1] >= 43) && !(m[0][1] <= 41))\n diff --git a/test/libsolidity/smtCheckerTests/types/abi_type_type_1.sol b/test/libsolidity/smtCheckerTests/types/abi_type_type_1.sol index d4207bc860..3effe1c05e 100644 --- a/test/libsolidity/smtCheckerTests/types/abi_type_type_1.sol +++ b/test/libsolidity/smtCheckerTests/types/abi_type_type_1.sol @@ -7,4 +7,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (107-128): CHC: Assertion violation happens here.\nCounterexample:\n\na = true\nx = 1\n\nTransaction trace:\nC.constructor()\nC.f(d) +// Warning 6328: (107-128): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/types/address_staticcall.sol b/test/libsolidity/smtCheckerTests/types/address_staticcall.sol index 11b862a10c..9d00904ad7 100644 --- a/test/libsolidity/smtCheckerTests/types/address_staticcall.sol +++ b/test/libsolidity/smtCheckerTests/types/address_staticcall.sol @@ -10,7 +10,8 @@ contract C assert(success); assert(x == 0); assert(map[0] == 0); - assert(localMap[0] == 0); + // Disabled because of Spacer's seg fault + //assert(localMap[0] == 0); } } // ==== @@ -18,6 +19,7 @@ contract C // SMTEngine: all // SMTIgnoreCex: yes // ---- +// Warning 2072: (127-166): Unused local variable. // Warning 2072: (191-207): Unused local variable. // Warning 6328: (233-248): CHC: Assertion violation happens here. -// Info 1180: Reentrancy property(ies) for :C:\n!( >= 2)\n!( >= 3)\n!( >= 4)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(success)\n = 2 -> Assertion failed at assert(x == 0)\n = 3 -> Assertion failed at assert(map[0] == 0)\n = 4 -> Assertion failed at assert(localMap[0] == 0)\n +// Info 1180: Reentrancy property(ies) for :C:\n!( >= 2)\n!( >= 3)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(success)\n = 2 -> Assertion failed at assert(x == 0)\n = 3 -> Assertion failed at assert(map[0] == 0)\n diff --git a/test/libsolidity/smtCheckerTests/types/bool_simple_2.sol b/test/libsolidity/smtCheckerTests/types/bool_simple_2.sol index 44daa89128..ce35a65054 100644 --- a/test/libsolidity/smtCheckerTests/types/bool_simple_2.sol +++ b/test/libsolidity/smtCheckerTests/types/bool_simple_2.sol @@ -6,4 +6,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (66-80): CHC: Assertion violation happens here.\nCounterexample:\n\nx = true\ny = false\n\nTransaction trace:\nC.constructor()\nC.f(true, false) +// Warning 6328: (66-80): CHC: Assertion violation happens here.\nCounterexample:\n\nx = false\ny = true\n\nTransaction trace:\nC.constructor()\nC.f(false, true) diff --git a/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol b/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol index b55293231f..320d7dd10e 100644 --- a/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol +++ b/test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol @@ -32,6 +32,5 @@ 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 1180: Contract invariant(s) for :C:\n!(a.length <= 4)\n +// Info 1180: Contract invariant(s) for :C:\n!(a.length <= 4)\n!(a[2].length <= 2)\n diff --git a/test/libsolidity/smtCheckerTests/userTypes/user_abi_1.sol b/test/libsolidity/smtCheckerTests/userTypes/user_abi_1.sol index 1d31cbe3d2..e4a68df6b4 100644 --- a/test/libsolidity/smtCheckerTests/userTypes/user_abi_1.sol +++ b/test/libsolidity/smtCheckerTests/userTypes/user_abi_1.sol @@ -11,4 +11,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (188-212): CHC: Assertion violation happens here.\nCounterexample:\n\ny = 2437\n\nTransaction trace:\nC.constructor()\nC.f(data) +// Warning 6328: (188-212): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/userTypes/user_abi_2.sol b/test/libsolidity/smtCheckerTests/userTypes/user_abi_2.sol index a4c4a3a29e..358e5404ea 100644 --- a/test/libsolidity/smtCheckerTests/userTypes/user_abi_2.sol +++ b/test/libsolidity/smtCheckerTests/userTypes/user_abi_2.sol @@ -11,4 +11,4 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (192-226): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.f(data) +// Warning 6328: (192-226): CHC: Assertion violation happens here. From 0c34d9df88434f48cee3b6b3f97e7097eb1a747f Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Tue, 23 Nov 2021 18:54:44 +0100 Subject: [PATCH 0141/1748] Adjust tests for nondeterminism --- .../array_members/push_storage_ref_unsafe_aliasing.sol | 7 ++++--- .../smtCheckerTests/external_calls/call_safe.sol | 2 +- .../external_calls/external_single_inc.sol | 3 ++- .../smtCheckerTests/functions/functions_external_1.sol | 3 +-- test/libsolidity/smtCheckerTests/try_catch/try_4.sol | 9 +++------ 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/test/libsolidity/smtCheckerTests/array_members/push_storage_ref_unsafe_aliasing.sol b/test/libsolidity/smtCheckerTests/array_members/push_storage_ref_unsafe_aliasing.sol index 87b9d92bf3..a8669fb601 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_storage_ref_unsafe_aliasing.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_storage_ref_unsafe_aliasing.sol @@ -13,7 +13,8 @@ contract C { // ==== // SMTEngine: all // SMTIgnoreOS: macos +// SMTIgnoreCex: yes // ---- -// Warning 6368: (188-192): CHC: Out of bounds access happens here.\nCounterexample:\na = []\nb = [32]\n\nTransaction trace:\nC.constructor()\nState: a = []\nC.f() -// Warning 6368: (188-195): CHC: Out of bounds access happens here.\nCounterexample:\n\nb = [32]\n\nTransaction trace:\nC.constructor()\nState: a = []\nC.f() -// Warning 6328: (181-202): CHC: Assertion violation happens here.\nCounterexample:\n\nb = [32]\n\nTransaction trace:\nC.constructor()\nState: a = []\nC.f() +// Warning 6368: (188-192): CHC: Out of bounds access happens here. +// Warning 6368: (188-195): CHC: Out of bounds access happens here. +// Warning 6328: (181-202): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol b/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol index f4f9d15ad4..e4e3abc24f 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/call_safe.sol @@ -7,7 +7,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreInv: yes // ---- // Warning 2072: (57-63): Unused local variable. // Warning 2072: (65-82): Unused local variable. -// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n((!(x <= 0) || ( <= 0)) && (!(x <= 0) || (x' <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_single_inc.sol b/test/libsolidity/smtCheckerTests/external_calls/external_single_inc.sol index 994fbde16f..7b73311a0b 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_single_inc.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_single_inc.sol @@ -22,5 +22,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreCex: yes // ---- -// Warning 6328: (223-240): CHC: Assertion violation happens here.\nCounterexample:\nx = 1, y = 1, d = 0\noldX = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0, y = 0, d = 0\nC.inc()\nState: x = 0, y = 1, d = 0\nC.f()\n d.d() -- untrusted external call, synthesized as:\n C.inc() -- reentrant call +// Warning 6328: (223-240): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol b/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol index 19dd010a5f..3a87f34c9d 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_external_1.sol @@ -17,5 +17,4 @@ contract C // ==== // SMTEngine: all // SMTIgnoreOS: macos -// ---- -// Info 1180: Contract invariant(s) for :C:\n(x <= 0)\nReentrancy property(ies) for :C:\n!( = 1)\n((!( >= 2) || !(x <= 0)) && (!(x <= 0) || (x' <= 0)))\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == y)\n = 2 -> Assertion failed at assert(x == y)\n +// SMTIgnoreInv: yes diff --git a/test/libsolidity/smtCheckerTests/try_catch/try_4.sol b/test/libsolidity/smtCheckerTests/try_catch/try_4.sol index 0abf62df8e..289f3943d7 100644 --- a/test/libsolidity/smtCheckerTests/try_catch/try_4.sol +++ b/test/libsolidity/smtCheckerTests/try_catch/try_4.sol @@ -14,7 +14,7 @@ contract C { function f() public { x = 0; try d.d() { - assert(x == 0); // should fail, x can be anything here + //assert(x == 0); // should fail, x can be anything here } catch { assert(x == 0); // should hold, all changes to x has been reverted assert(x == 1); // should fail @@ -25,8 +25,5 @@ contract C { // SMTEngine: all // SMTIgnoreCex: yes // ---- -// Warning 1218: (178-192): CHC: Error trying to invoke SMT solver. -// Warning 6328: (178-192): CHC: Assertion violation might happen here. -// Warning 6328: (318-332): CHC: Assertion violation happens here. -// Info 1180: Reentrancy property(ies) for :C:\n!( = 2)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n = 2 -> Assertion failed at assert(x == 0)\n = 3 -> Assertion failed at assert(x == 1)\n -// Warning 4661: (178-192): BMC: Assertion violation happens here. +// Warning 6328: (320-334): CHC: Assertion violation happens here. +// Info 1180: Reentrancy property(ies) for :C:\n!( = 1)\n = 0 -> no errors\n = 1 -> Assertion failed at assert(x == 0)\n = 2 -> Assertion failed at assert(x == 1)\n From 6cff73af71542fe6a00975b53b3380c234295fac Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Tue, 23 Nov 2021 18:59:26 +0100 Subject: [PATCH 0142/1748] update osx z3 hash --- .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 a973988a6e..36d3367746 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -65,7 +65,7 @@ then z3_dir="z3-${z3_version}-x64-osx-10.16" z3_package="${z3_dir}.zip" wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_package}" - validate_checksum "$z3_package" a1f6ef3c99456147c4d3f2652dc6bc90951c4ab3fe7741a255eb794f0ab8938c + validate_checksum "$z3_package" 191b26be2b617b2dffffce139d77abcd7e584859efbc10a58d01a1d7830697a4 unzip "$z3_package" rm "$z3_package" cp "${z3_dir}/bin/libz3.a" /usr/local/lib From a2588533e504c2a46827fe3ed87362f2bd7c4f32 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 24 Nov 2021 11:38:22 +0100 Subject: [PATCH 0143/1748] macos nondeterminism --- .../array_members/length_1d_struct_array_2d_1.sol | 1 + .../libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol | 1 + .../smtCheckerTests/blockchain_state/balance_receive_4.sol | 1 + .../blockchain_state/balance_receive_ext_calls.sol | 1 + .../branches_with_return/branches_in_modifiers_2.sol | 1 + .../control_flow/branches_with_return/triple_nested_if.sol | 1 + .../external_calls/external_call_with_value_3.sol | 1 + .../external_hash_known_code_state_reentrancy_unsafe.sol | 1 + .../operators/assignment_module_contract_member_variable.sol | 1 + .../smtCheckerTests/operators/compound_add_array_index.sol | 1 + .../smtCheckerTests/operators/compound_add_mapping.sol | 1 + .../smtCheckerTests/operators/compound_assignment_division_3.sol | 1 + .../smtCheckerTests/operators/compound_bitwise_or_int_1.sol | 1 + .../libsolidity/smtCheckerTests/special/tx_vars_chc_internal.sol | 1 + .../libsolidity/smtCheckerTests/userTypes/multisource_module.sol | 1 + 15 files changed, 15 insertions(+) diff --git a/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_2d_1.sol b/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_2d_1.sol index 71571d9448..ddda215df8 100644 --- a/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_2d_1.sol +++ b/test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_2d_1.sol @@ -20,5 +20,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Info 1180: Contract invariant(s) for :C:\n!(s1.arr.length <= 0)\n!(s2.arr.length <= 0)\n(((s2.arr[0].length + ((- 1) * s1.arr[0].length)) <= 0) && ((s1.arr[0].length + ((- 1) * s2.arr[0].length)) <= 0))\n diff --git a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol index 5920a4e747..0d16306b72 100644 --- a/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol +++ b/test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol @@ -17,5 +17,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (199-229): CHC: Assertion violation happens here.\nCounterexample:\nb = [1]\n\nTransaction trace:\nC.constructor()\nState: b = []\nC.g() diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol index 3e3e564317..4fa420ff16 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol @@ -11,6 +11,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 4984: (82-85): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. // Warning 4984: (154-160): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here. diff --git a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol index 1ee90e41d0..96223b7e94 100644 --- a/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol +++ b/test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol @@ -12,6 +12,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 1218: (131-165): CHC: Error trying to invoke SMT solver. // Warning 6328: (131-165): CHC: Assertion violation might happen here. diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol index 4241fa9e29..f08a26bf70 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol @@ -42,6 +42,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (255-269): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.test()\n C.reset_if_overflow() -- internal call // Warning 6328: (502-519): CHC: Assertion violation happens here.\nCounterexample:\nx = 2\noldx = 1\n\nTransaction trace:\nC.constructor()\nState: x = 0\nC.set(1)\nState: x = 1\nC.test()\n C.reset_if_overflow() -- internal call diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/triple_nested_if.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/triple_nested_if.sol index 09ee2b2b24..472ef8785e 100644 --- a/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/triple_nested_if.sol +++ b/test/libsolidity/smtCheckerTests/control_flow/branches_with_return/triple_nested_if.sol @@ -17,5 +17,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Info 1180: Contract invariant(s) for :C:\n((c <= 0) && (a <= 0) && (b <= 0))\n 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 d0e4c84aa6..2a535329ac 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 @@ -12,6 +12,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // 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 diff --git a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe.sol b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe.sol index d871d6e134..b3b43980ab 100644 --- a/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe.sol +++ b/test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe.sol @@ -34,6 +34,7 @@ contract C { // ==== // SMTEngine: all // SMTIgnoreCex: yes +// SMTIgnoreOS: macos // ---- // Warning 6328: (348-362): CHC: Assertion violation happens here. // Warning 6328: (366-392): CHC: Assertion violation happens here. 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 18869ee3a3..781476de25 100644 --- a/test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol +++ b/test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol @@ -27,6 +27,7 @@ contract A { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (AASource:159-178): CHC: Assertion violation happens here.\nCounterexample:\nx = (- 1), y = (- 2)\n\nTransaction trace:\nA.constructor()\nState: x = 0, y = 0\nA.a()\nState: x = (- 2), y = (- 2)\nA.a() // Warning 6328: (AASource:370-386): CHC: Assertion violation happens here.\nCounterexample:\nx = 8, y = (- 2)\n\nTransaction trace:\nA.constructor()\nState: x = 0, y = 0\nA.a() diff --git a/test/libsolidity/smtCheckerTests/operators/compound_add_array_index.sol b/test/libsolidity/smtCheckerTests/operators/compound_add_array_index.sol index 424baf927a..1c6e205d3f 100644 --- a/test/libsolidity/smtCheckerTests/operators/compound_add_array_index.sol +++ b/test/libsolidity/smtCheckerTests/operators/compound_add_array_index.sol @@ -18,5 +18,6 @@ contract C } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (262-284): CHC: Assertion violation happens here.\nCounterexample:\narray = [299, 0]\nx = 99\np = 0\n\nTransaction trace:\nC.constructor()\nState: array = [0, 0]\nC.f(99, 0) diff --git a/test/libsolidity/smtCheckerTests/operators/compound_add_mapping.sol b/test/libsolidity/smtCheckerTests/operators/compound_add_mapping.sol index 4169357d1b..ab133cefc9 100644 --- a/test/libsolidity/smtCheckerTests/operators/compound_add_mapping.sol +++ b/test/libsolidity/smtCheckerTests/operators/compound_add_mapping.sol @@ -11,5 +11,6 @@ contract C } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (165-185): CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\np = 0\n\nTransaction trace:\nC.constructor()\nC.f(0, 0) diff --git a/test/libsolidity/smtCheckerTests/operators/compound_assignment_division_3.sol b/test/libsolidity/smtCheckerTests/operators/compound_assignment_division_3.sol index e762eb4be3..aa90aa2529 100644 --- a/test/libsolidity/smtCheckerTests/operators/compound_assignment_division_3.sol +++ b/test/libsolidity/smtCheckerTests/operators/compound_assignment_division_3.sol @@ -10,5 +10,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (162-181): CHC: Assertion violation happens here.\nCounterexample:\n\nx = 2\np = 0\n\nTransaction trace:\nC.constructor()\nC.f(2, 0) diff --git a/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_int_1.sol b/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_int_1.sol index 8f7c69b2cd..fdd8c55cce 100644 --- a/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_int_1.sol +++ b/test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_int_1.sol @@ -9,6 +9,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6368: (76-81): CHC: Out of bounds access might happen here. // Warning 6368: (76-84): CHC: Out of bounds access might happen here. diff --git a/test/libsolidity/smtCheckerTests/special/tx_vars_chc_internal.sol b/test/libsolidity/smtCheckerTests/special/tx_vars_chc_internal.sol index 4c3682c60a..95e3390b45 100644 --- a/test/libsolidity/smtCheckerTests/special/tx_vars_chc_internal.sol +++ b/test/libsolidity/smtCheckerTests/special/tx_vars_chc_internal.sol @@ -19,5 +19,6 @@ contract C { } // ==== // SMTEngine: chc +// SMTIgnoreOS: macos // ---- // Warning 6328: (343-377): CHC: Assertion violation happens here.\nCounterexample:\ngas = 0, origin = 0x52f7\n\nTransaction trace:\nC.constructor()\nState: gas = 0, origin = 0x0\nC.f(){ tx.gasprice: 0, tx.origin: 0x52f7 }\n C.g() -- internal call diff --git a/test/libsolidity/smtCheckerTests/userTypes/multisource_module.sol b/test/libsolidity/smtCheckerTests/userTypes/multisource_module.sol index ee3277d1bc..491b8600d9 100644 --- a/test/libsolidity/smtCheckerTests/userTypes/multisource_module.sol +++ b/test/libsolidity/smtCheckerTests/userTypes/multisource_module.sol @@ -15,6 +15,7 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreOS: macos // ---- // Warning 6328: (s2.sol:259-292): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.h()\n C.f(5) -- internal call\n C.f(5) -- internal call // Warning 6328: (s2.sol:346-377): CHC: Assertion violation happens here.\nCounterexample:\n\n\nTransaction trace:\nC.constructor()\nC.h()\n C.f(5) -- internal call\n C.f(5) -- internal call\n C.g(1) -- internal call\n C.g(1) -- internal call From aa1a17072f5446dd553818c050bdbfd54aca635c Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Tue, 23 Nov 2021 12:03:43 +0100 Subject: [PATCH 0144/1748] Update z3 version in our docker files --- scripts/docker/buildpack-deps/Dockerfile.emscripten | 4 ++-- .../docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz | 4 ++-- scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 | 2 +- scripts/docker/buildpack-deps/Dockerfile.ubuntu2004.clang | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.emscripten b/scripts/docker/buildpack-deps/Dockerfile.emscripten index 9a3ca36af4..5f86b1e197 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.emscripten +++ b/scripts/docker/buildpack-deps/Dockerfile.emscripten @@ -33,12 +33,12 @@ # Using $(em-config CACHE)/sysroot/usr seems to work, though, and still has cmake find the # dependencies automatically. FROM emscripten/emsdk:2.0.33 AS base -LABEL version="7" +LABEL version="8" ADD emscripten.jam /usr/src RUN set -ex; \ cd /usr/src; \ - git clone https://github.com/Z3Prover/z3.git -b z3-4.8.12 --depth 1 ; \ + git clone https://github.com/Z3Prover/z3.git -b z3-4.8.13 --depth 1 ; \ cd z3; \ mkdir build; \ cd build; \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz index 48e9839dd9..0b1ed6125d 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz @@ -22,7 +22,7 @@ # (c) 2016-2021 solidity contributors. #------------------------------------------------------------------------------ FROM gcr.io/oss-fuzz-base/base-clang:latest as base -LABEL version="13" +LABEL version="14" ARG DEBIAN_FRONTEND=noninteractive @@ -61,7 +61,7 @@ RUN set -ex; \ # Z3 RUN set -ex; \ - git clone --depth 1 -b z3-4.8.12 https://github.com/Z3Prover/z3.git \ + git clone --depth 1 -b z3-4.8.13 https://github.com/Z3Prover/z3.git \ /usr/src/z3; \ cd /usr/src/z3; \ mkdir build; \ diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004 index 63f09e5138..8ed35d67e9 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="8" +LABEL version="9" ARG DEBIAN_FRONTEND=noninteractive diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004.clang b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004.clang index 1f96e41d5c..0ac9d4abf8 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004.clang +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu2004.clang @@ -22,7 +22,7 @@ # (c) 2016-2019 solidity contributors. #------------------------------------------------------------------------------ FROM buildpack-deps:focal AS base -LABEL version="8" +LABEL version="9" ARG DEBIAN_FRONTEND=noninteractive From 6b69791f2bab4e543ec70882a6ea471ec6053462 Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Wed, 24 Nov 2021 14:24:56 +0100 Subject: [PATCH 0145/1748] Disabling Clang-14 bitwise instead of logical warning in Hera build. --- .../docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz index 0b1ed6125d..64260c1b9c 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz @@ -109,7 +109,7 @@ RUN set -ex; \ cd hera; \ mkdir build; \ cd build; \ - cmake -G Ninja -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="/usr" ..; \ + cmake -G Ninja -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_FLAGS="-Wno-bitwise-instead-of-logical" -DCMAKE_INSTALL_PREFIX="/usr" ..; \ ninja; \ ninja install/strip; \ rm -rf /usr/src/hera From 1c8d430b8220733c41485d87e134865702a00a13 Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Wed, 24 Nov 2021 17:55:52 +0100 Subject: [PATCH 0146/1748] Remove Hera as a dependency for oss-fuzz Docker image. --- .../Dockerfile.ubuntu1604.clang.ossfuzz | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz b/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz index 64260c1b9c..1d00eabce8 100644 --- a/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz +++ b/scripts/docker/buildpack-deps/Dockerfile.ubuntu1604.clang.ossfuzz @@ -102,18 +102,6 @@ RUN set -ex; \ ninja install/strip; \ rm -rf /usr/src/evmone -# HERA -RUN set -ex; \ - cd /usr/src; \ - git clone --branch="v0.5.0" --depth 1 --recurse-submodules https://github.com/ewasm/hera.git; \ - cd hera; \ - mkdir build; \ - cd build; \ - cmake -G Ninja -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_FLAGS="-Wno-bitwise-instead-of-logical" -DCMAKE_INSTALL_PREFIX="/usr" ..; \ - ninja; \ - ninja install/strip; \ - rm -rf /usr/src/hera - # gmp RUN set -ex; \ # Replace system installed libgmp static library From 26ac84300e3ab2206a931cb955911f4ca5d46254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 23 Nov 2021 17:09:50 +0100 Subject: [PATCH 0147/1748] CI: Extract workflow name without jq --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fb3abb37af..92c3d030fd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,7 +51,7 @@ commands: # Workflow name is not exposed as an env variable. Has to be queried from the API. # The name is not critical so if anything fails, use the raw workflow ID as a fallback. workflow_info=$(curl --silent "https://circleci.com/api/v2/workflow/${CIRCLE_WORKFLOW_ID}") || true - workflow_name=$(echo "$workflow_info" | jq --raw-output .name || echo "$CIRCLE_WORKFLOW_ID") + workflow_name=$(echo "$workflow_info" | grep -E '"\s*name"\s*:\s*".*"' | cut -d \" -f 4 || echo "$CIRCLE_WORKFLOW_ID") [[ "<< parameters.event >>" == "failure" ]] && message=" ❌ [${workflow_name}] Job **${CIRCLE_JOB}** failed on **${CIRCLE_BRANCH}**. Please see [build ${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." [[ "<< parameters.event >>" == "success" ]] && message=" ✅ [${workflow_name}] Job **${CIRCLE_JOB}** succeeded on **${CIRCLE_BRANCH}**. Please see [build ${CIRCLE_BUILD_NUM}](${CIRCLE_BUILD_URL}) for details." From 674b1ecf3f78e61a17a2cd3fd6c6e8bf5d56b5ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 5 Nov 2021 17:38:25 +0100 Subject: [PATCH 0148/1748] CI: Change the default node version in t_ems_ext from 14 to latest --- .circleci/config.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fb3abb37af..398e73e49e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -946,8 +946,8 @@ jobs: type: integer default: 0 nodejs_version: - type: integer - default: 14 + type: string + default: latest docker: - image: circleci/node:<> # NOTE: Each external test does 3 separate compile&test runs @@ -1205,28 +1205,32 @@ workflows: name: t_ems_compile_ext_colony project: colony compile_only: 1 + nodejs_version: '14' - t_ems_ext: <<: *workflow_emscripten name: t_ems_compile_ext_gnosis project: gnosis compile_only: 1 + nodejs_version: '14' - t_ems_ext: <<: *workflow_emscripten name: t_ems_compile_ext_gnosis_v2 project: gnosis-v2 compile_only: 1 + nodejs_version: '14' - t_ems_ext: <<: *workflow_emscripten name: t_ems_compile_ext_zeppelin project: zeppelin compile_only: 1 + nodejs_version: '14' - t_ems_ext: <<: *workflow_emscripten name: t_ems_compile_ext_ens project: ens compile_only: 1 # NOTE: One of the dependencies (fsevents) fails to build its native extension on node.js 12+. - nodejs_version: 10 + nodejs_version: '10' # FIXME: Gnosis tests are pretty flaky right now. They often fail on CircleCI due to random ProviderError # and there are also other less frequent problems. See https://github.com/gnosis/safe-contracts/issues/216. @@ -1235,23 +1239,24 @@ workflows: # name: t_ems_test_ext_gnosis # project: gnosis # # NOTE: Tests do not start on node.js 14 ("ganache-cli exited early with code 1"). - # nodejs_version: 12 + # nodejs_version: '12' - t_ems_ext: <<: *workflow_emscripten name: t_ems_test_ext_gnosis_v2 project: gnosis-v2 # NOTE: Tests do not start on node.js 14 ("ganache-cli exited early with code 1"). - nodejs_version: 12 + nodejs_version: '12' - t_ems_ext: <<: *workflow_emscripten name: t_ems_test_ext_zeppelin project: zeppelin + nodejs_version: '14' - t_ems_ext: <<: *workflow_emscripten name: t_ems_test_ext_ens project: ens # NOTE: One of the dependencies (fsevents) fails to build its native extension on node.js 12+. - nodejs_version: 10 + nodejs_version: '10' # Windows build and tests - b_win: *workflow_trigger_on_tags From 9f59d1746b29591543ea103876a712ed21444845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 26 Oct 2021 15:49:00 +0200 Subject: [PATCH 0149/1748] Fix OpenZeppelin external tests to actually use Hardhat and the binary built in CI --- .circleci/config.yml | 4 +- test/externalTests/common.sh | 95 ++++++++++++++++++++++++++++++++++ test/externalTests/zeppelin.sh | 12 ++--- 3 files changed, 103 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 398e73e49e..7a24abab4f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1223,7 +1223,6 @@ workflows: name: t_ems_compile_ext_zeppelin project: zeppelin compile_only: 1 - nodejs_version: '14' - t_ems_ext: <<: *workflow_emscripten name: t_ems_compile_ext_ens @@ -1250,7 +1249,8 @@ workflows: <<: *workflow_emscripten name: t_ems_test_ext_zeppelin project: zeppelin - nodejs_version: '14' + # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" + nodejs_version: '16' - t_ems_ext: <<: *workflow_emscripten name: t_ems_test_ext_ens diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 2519a0f878..7e651d8c0b 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -74,6 +74,7 @@ function setup_solcjs npm install cp "$soljson" soljson.js SOLCVERSION=$(./solcjs --version) + SOLCVERSION_SHORT=$(echo "$SOLCVERSION" | sed -En 's/^([0-9.]+).*\+commit\.[0-9a-f]+.*$/\1/p') printLog "Using solcjs version $SOLCVERSION" cd .. } @@ -161,6 +162,40 @@ function force_truffle_compiler_settings echo "module.exports['compilers'] = $(truffle_compiler_settings "$solc_path" "$level" "$evm_version");" >> "$config_file" } +function force_hardhat_compiler_binary +{ + local config_file="$1" + local solc_path="$2" + + printLog "Configuring Hardhat..." + echo "-------------------------------------" + echo "Config file: ${config_file}" + echo "Compiler path: ${solc_path}" + hardhat_solc_build_subtask "$SOLCVERSION_SHORT" "$SOLCVERSION" "$solc_path" >> "$config_file" +} + +function force_hardhat_compiler_settings +{ + local config_file="$1" + local level="$2" + local evm_version="${3:-"$CURRENT_EVM_VERSION"}" + + printLog "Configuring Hardhat..." + echo "-------------------------------------" + echo "Config file: ${config_file}" + echo "Optimization level: ${level}" + echo "Optimizer settings: $(optimizer_settings_for_level "$level")" + echo "EVM version: ${evm_version}" + echo "Compiler version: ${SOLCVERSION_SHORT}" + echo "Compiler version (full): ${SOLCVERSION}" + echo "-------------------------------------" + + { + echo -n 'module.exports["solidity"] = ' + hardhat_compiler_settings "$SOLCVERSION_SHORT" "$level" "$evm_version" + } >> "$config_file" +} + function truffle_verify_compiler_version { local solc_version="$1" @@ -170,11 +205,26 @@ function truffle_verify_compiler_version grep "$full_solc_version" --with-filename --recursive build/contracts || fail "Wrong compiler version detected." } +function hardhat_verify_compiler_version +{ + local solc_version="$1" + local full_solc_version="$2" + + printLog "Verify that the correct version (${solc_version}/${full_solc_version}) of the compiler was used to compile the contracts..." + grep '"solcVersion": "'"${solc_version}"'"' --with-filename artifacts/build-info/*.json || fail "Wrong compiler version detected." + grep '"solcLongVersion": "'"${full_solc_version}"'"' --with-filename artifacts/build-info/*.json || fail "Wrong compiler version detected." +} + function truffle_clean { rm -rf build/ } +function hardhat_clean +{ + rm -rf artifacts/ cache/ +} + function run_test { local compile_fn="$1" @@ -221,6 +271,39 @@ function truffle_compiler_settings echo "}" } +function hardhat_solc_build_subtask { + local solc_version="$1" + local full_solc_version="$2" + local solc_path="$3" + + echo "const {TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD} = require('hardhat/builtin-tasks/task-names');" + echo "const assert = require('assert');" + echo + echo "subtask(TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD, async (args, hre, runSuper) => {" + echo " assert(args.solcVersion == '${solc_version}', 'Unexpected solc version: ' + args.solcVersion)" + echo " return {" + echo " compilerPath: '$(realpath "$solc_path")'," + echo " isSolcJs: true," + echo " version: args.solcVersion," + echo " longVersion: '${full_solc_version}'" + echo " }" + echo "})" +} + +function hardhat_compiler_settings { + local solc_version="$1" + local level="$2" + local evm_version="$3" + + echo "{" + echo " version: '${solc_version}'," + echo " settings: {" + echo " optimizer: $(optimizer_settings_for_level "$level")," + echo " evmVersion: '${evm_version}'" + echo " }" + echo "}" +} + function compile_and_run_test { local compile_fn="$1" @@ -252,6 +335,18 @@ function truffle_run_test compile_and_run_test compile_fn test_fn truffle_verify_compiler_version } +function hardhat_run_test +{ + local config_file="$1" + local optimizer_level="$2" + local compile_fn="$3" + local test_fn="$4" + + hardhat_clean + force_hardhat_compiler_settings "$config_file" "$optimizer_level" + compile_and_run_test compile_fn test_fn hardhat_verify_compiler_version +} + function external_test { local name="$1" diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 24e576b931..cd290b860f 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -27,14 +27,14 @@ source test/externalTests/common.sh verify_input "$1" SOLJSON="$1" -function compile_fn { npx truffle compile; } -function test_fn { npm run test; } +function compile_fn { npm run compile; } +function test_fn { npm test; } function zeppelin_test { local repo="https://github.com/OpenZeppelin/openzeppelin-contracts.git" local branch=master - local config_file="truffle-config.js" + local config_file="hardhat.config.js" local min_optimizer_level=1 local max_optimizer_level=3 @@ -46,14 +46,14 @@ function zeppelin_test download_project "$repo" "$branch" "$DIR" neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + force_hardhat_compiler_binary "$config_file" "$SOLJSON" + force_hardhat_compiler_settings "$config_file" "$min_optimizer_level" npm install replace_version_pragmas - force_solc_modules "${DIR}/solc" for level in $selected_optimizer_levels; do - truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + hardhat_run_test "$config_file" "$level" compile_fn test_fn done } From 5e59325d0692665166a072555025152b8d1a63b2 Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Sat, 13 Nov 2021 01:31:11 +0530 Subject: [PATCH 0150/1748] relocated downloads section in versions flyout menu and added downloads Hint in index.html --- docs/_templates/versions.html | 8 ++++---- docs/index.rst | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/_templates/versions.html b/docs/_templates/versions.html index f680b6506d..fcd79cb3fc 100644 --- a/docs/_templates/versions.html +++ b/docs/_templates/versions.html @@ -13,13 +13,13 @@
-
{{ _('Versions') }}
{% for slug, url in versions %} -
{{ slug }}
+
{{ _('Downloads') }}
{% for type, url in downloads %} +
{{ type }}
{% endfor %}
-
{{ _('Downloads') }}
{% for type, url in downloads %} -
{{ type }}
+
{{ _('Versions') }}
{% for slug, url in versions %} +
{{ slug }}
{% endfor %}
diff --git a/docs/index.rst b/docs/index.rst index 60b3d61fac..1086df9a7b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -31,6 +31,12 @@ a 0.y.z version number `to indicate this fast pace of change ` for more details. +.. Hint:: + + You can download this documentation as PDF, HTML or Epub by clicking on the versions + flyout menu in the left bottom corner and selecting the preferred download format. + + Getting Started --------------- From ecf6c8e122da75423bf680a7a0ab62a882654c3e Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Sat, 13 Nov 2021 01:41:38 +0530 Subject: [PATCH 0151/1748] trailing whitespace removed in index.rst as per the requirements of a syntax test --- docs/_templates/versions.html | 8 ++++++-- docs/index.rst | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/_templates/versions.html b/docs/_templates/versions.html index fcd79cb3fc..9168179dfd 100644 --- a/docs/_templates/versions.html +++ b/docs/_templates/versions.html @@ -1,7 +1,11 @@ {# Add rst-badge after rst-versions for small badge style. #}
- RTD + {% for type, url in downloads %} + {% if type == 'PDF' %} + {{ type }} + {% endif %} + {% endfor %} @@ -33,4 +37,4 @@
- \ No newline at end of file + diff --git a/docs/index.rst b/docs/index.rst index 1086df9a7b..f69f8692b0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -33,8 +33,8 @@ 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 left bottom corner and selecting the preferred download format. + 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. Getting Started From 49d9f334aa3490590eeb4a339cf74565e38052ea Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Sun, 21 Nov 2021 00:14:34 +0530 Subject: [PATCH 0152/1748] Extracted some test cases from SolidityEndToEnd.cpp --- test/libsolidity/SolidityEndToEndTest.cpp | 210 ------------------ .../enums/invalid_enum_logged.sol | 24 ++ .../library_staticcall_delegatecall.sol | 20 ++ .../memory_types_initialisation.sol | 17 ++ .../strings/constant_string_literal.sol | 25 +++ .../semanticTests/strings/return_string.sol | 20 ++ .../structs/packed_storage_structs_delete.sol | 27 +++ .../variables/storing_invalid_boolean.sol | 35 +++ 8 files changed, 168 insertions(+), 210 deletions(-) create mode 100644 test/libsolidity/semanticTests/enums/invalid_enum_logged.sol create mode 100644 test/libsolidity/semanticTests/libraries/library_staticcall_delegatecall.sol create mode 100644 test/libsolidity/semanticTests/memoryManagement/memory_types_initialisation.sol create mode 100644 test/libsolidity/semanticTests/strings/constant_string_literal.sol create mode 100644 test/libsolidity/semanticTests/strings/return_string.sol create mode 100644 test/libsolidity/semanticTests/structs/packed_storage_structs_delete.sol create mode 100644 test/libsolidity/semanticTests/variables/storing_invalid_boolean.sol diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index e5a6b8cf7c..4731149618 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1607,30 +1607,6 @@ BOOST_AUTO_TEST_CASE(library_call_protection) ) } -BOOST_AUTO_TEST_CASE(library_staticcall_delegatecall) -{ - char const* sourceCode = R"( - library Lib { - function x() public view returns (uint) { - return 1; - } - } - contract Test { - uint t; - function f() public returns (uint) { - t = 2; - return this.g(); - } - function g() public view returns (uint) { - return Lib.x(); - } - } - )"; - compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs(1)); -} - BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory) { char const* sourceCode = R"( @@ -1786,49 +1762,6 @@ BOOST_AUTO_TEST_CASE(copy_from_calldata_removes_bytes_data) ); } -BOOST_AUTO_TEST_CASE(storing_invalid_boolean) -{ - char const* sourceCode = R"( - contract C { - event Ev(bool); - bool public perm; - function set() public returns(uint) { - bool tmp; - assembly { - tmp := 5 - } - perm = tmp; - return 1; - } - function ret() public returns(bool) { - bool tmp; - assembly { - tmp := 5 - } - return tmp; - } - function ev() public returns(uint) { - bool tmp; - assembly { - tmp := 5 - } - emit Ev(tmp); - return 1; - } - } - )"; - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("set()"), encodeArgs(1)); - ABI_CHECK(callContractFunction("perm()"), encodeArgs(1)); - ABI_CHECK(callContractFunction("ret()"), encodeArgs(1)); - ABI_CHECK(callContractFunction("ev()"), encodeArgs(1)); - BOOST_REQUIRE_EQUAL(numLogs(), 1); - BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); - BOOST_CHECK(logData(0) == encodeArgs(1)); - BOOST_REQUIRE_EQUAL(numLogTopics(0), 1); - BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Ev(bool)"))); -} - BOOST_AUTO_TEST_CASE(struct_referencing) { static char const* sourceCode = R"( @@ -2059,70 +1992,6 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_abi) // ABI_CHECK(callContractFunction("f()"), encodeArgs(5)); //} -BOOST_AUTO_TEST_CASE(packed_storage_structs_delete) -{ - char const* sourceCode = R"( - contract C { - struct str { uint8 a; uint16 b; uint8 c; } - uint8 x; - uint16 y; - str data; - function test() public returns (uint) { - x = 1; - y = 2; - data.a = 2; - data.b = 0xabcd; - data.c = 0xfa; - if (x != 1 || y != 2 || data.a != 2 || data.b != 0xabcd || data.c != 0xfa) - return 2; - delete y; - delete data.b; - if (x != 1 || y != 0 || data.a != 2 || data.b != 0 || data.c != 0xfa) - return 3; - delete x; - delete data; - return 1; - } - } - )"; - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("test()"), encodeArgs(1)); - BOOST_CHECK(storageEmpty(m_contractAddress)); -} - -BOOST_AUTO_TEST_CASE(invalid_enum_logged) -{ - char const* sourceCode = R"( - contract C { - enum X { A, B } - event Log(X); - - function test_log() public returns (uint) { - X garbled = X.A; - assembly { - garbled := 5 - } - emit Log(garbled); - return 1; - } - function test_log_ok() public returns (uint) { - X x = X.A; - emit Log(x); - return 1; - } - } - )"; - compileAndRun(sourceCode, 0, "C"); - ABI_CHECK(callContractFunction("test_log_ok()"), encodeArgs(u256(1))); - BOOST_REQUIRE_EQUAL(numLogs(), 1); - BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); - BOOST_REQUIRE_EQUAL(numLogTopics(0), 1); - BOOST_REQUIRE_EQUAL(logTopic(0, 0), util::keccak256(string("Log(uint8)"))); - BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(0))); - - ABI_CHECK(callContractFunction("test_log()"), panicData(PanicCode::EnumConversionError)); -} - BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund) { char const* sourceCode = R"( @@ -2164,31 +2033,6 @@ BOOST_AUTO_TEST_CASE(failing_send) BOOST_REQUIRE(callContractFunction("callHelper(address)", c_helperAddress) == encodeArgs(true, 20)); } -BOOST_AUTO_TEST_CASE(return_string) -{ - char const* sourceCode = R"( - contract Main { - string public s; - function set(string calldata _s) external { - s = _s; - } - function get1() public returns (string memory r) { - return s; - } - function get2() public returns (string memory r) { - r = s; - } - } - )"; - compileAndRun(sourceCode, 0, "Main"); - string s("Julia"); - bytes args = encodeArgs(u256(0x20), u256(s.length()), s); - BOOST_REQUIRE(callContractFunction("set(string)", asString(args)) == encodeArgs()); - ABI_CHECK(callContractFunction("get1()"), args); - ABI_CHECK(callContractFunction("get2()"), args); - ABI_CHECK(callContractFunction("s()"), args); -} - BOOST_AUTO_TEST_CASE(return_multiple_strings_of_various_sizes) { char const* sourceCode = R"( @@ -2343,28 +2187,6 @@ BOOST_AUTO_TEST_CASE(return_bytes_internal) } } -BOOST_AUTO_TEST_CASE(memory_types_initialisation) -{ - char const* sourceCode = R"( - contract Test { - mapping(uint=>uint) data; - function stat() public returns (uint[5] memory) - { - data[2] = 3; // make sure to use some memory - } - function dyn() public returns (uint[] memory) { stat(); } - function nested() public returns (uint[3][] memory) { stat(); } - function nestedStat() public returns (uint[3][7] memory) { stat(); } - } - )"; - compileAndRun(sourceCode, 0, "Test"); - - ABI_CHECK(callContractFunction("stat()"), encodeArgs(vector(5))); - ABI_CHECK(callContractFunction("dyn()"), encodeArgs(u256(0x20), u256(0))); - ABI_CHECK(callContractFunction("nested()"), encodeArgs(u256(0x20), u256(0))); - ABI_CHECK(callContractFunction("nestedStat()"), encodeArgs(vector(3 * 7))); -} - BOOST_AUTO_TEST_CASE(calldata_struct_short) { char const* sourceCode = R"( @@ -2718,38 +2540,6 @@ BOOST_AUTO_TEST_CASE(nested_mixed_string_as_public_mapping_key) ), encodeArgs(u256(i - 3))); } -BOOST_AUTO_TEST_CASE(constant_string_literal) -{ - char const* sourceCode = R"( - contract Test { - bytes32 constant public b = "abcdefghijklmnopq"; - string constant public x = "abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca"; - - constructor() { - string memory xx = x; - bytes32 bb = b; - } - function getB() public returns (bytes32) { return b; } - function getX() public returns (string memory) { return x; } - function getX2() public returns (string memory r) { r = x; } - function unused() public returns (uint) { - "unusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunused"; - return 2; - } - } - )"; - - compileAndRun(sourceCode); - string longStr = "abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca"; - string shortStr = "abcdefghijklmnopq"; - ABI_CHECK(callContractFunction("b()"), encodeArgs(shortStr)); - ABI_CHECK(callContractFunction("x()"), encodeDyn(longStr)); - ABI_CHECK(callContractFunction("getB()"), encodeArgs(shortStr)); - ABI_CHECK(callContractFunction("getX()"), encodeDyn(longStr)); - ABI_CHECK(callContractFunction("getX2()"), encodeDyn(longStr)); - ABI_CHECK(callContractFunction("unused()"), encodeArgs(2)); -} - BOOST_AUTO_TEST_CASE(library_call) { char const* sourceCode = R"( diff --git a/test/libsolidity/semanticTests/enums/invalid_enum_logged.sol b/test/libsolidity/semanticTests/enums/invalid_enum_logged.sol new file mode 100644 index 0000000000..33cec7482a --- /dev/null +++ b/test/libsolidity/semanticTests/enums/invalid_enum_logged.sol @@ -0,0 +1,24 @@ +contract C { + enum X { A, B } + event Log(X); + + function test_log() public returns (uint) { + X garbled = X.A; + assembly { + garbled := 5 + } + emit Log(garbled); + return 1; + } + function test_log_ok() public returns (uint) { + X x = X.A; + emit Log(x); + return 1; + } +} +// ==== +// compileViaYul: also +// ---- +// test_log_ok() -> 1 +// ~ emit Log(uint8): 0x00 +// test_log() -> FAILURE, hex"4e487b71", 0x21 diff --git a/test/libsolidity/semanticTests/libraries/library_staticcall_delegatecall.sol b/test/libsolidity/semanticTests/libraries/library_staticcall_delegatecall.sol new file mode 100644 index 0000000000..d566f71801 --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/library_staticcall_delegatecall.sol @@ -0,0 +1,20 @@ +library Lib { + function x() public view returns (uint) { + return 1; + } +} +contract Test { + uint t; + function f() public returns (uint) { + t = 2; + return this.g(); + } + function g() public view returns (uint) { + return Lib.x(); + } +} +// ==== +// compileViaYul: also +// ---- +// library: Lib +// f() -> 1 diff --git a/test/libsolidity/semanticTests/memoryManagement/memory_types_initialisation.sol b/test/libsolidity/semanticTests/memoryManagement/memory_types_initialisation.sol new file mode 100644 index 0000000000..7ad6b61672 --- /dev/null +++ b/test/libsolidity/semanticTests/memoryManagement/memory_types_initialisation.sol @@ -0,0 +1,17 @@ +contract Test { + mapping(uint=>uint) data; + function stat() public returns (uint[5] memory) + { + data[2] = 3; // make sure to use some memory + } + function dyn() public returns (uint[] memory) { stat(); } + function nested() public returns (uint[3][] memory) { stat(); } + function nestedStat() public returns (uint[3][7] memory) { stat(); } +} +// ==== +// compileViaYul: also +// ---- +// stat() -> 0, 0, 0, 0, 0 +// dyn() -> 0x20, 0 +// nested() -> 0x20, 0 +// nestedStat() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 diff --git a/test/libsolidity/semanticTests/strings/constant_string_literal.sol b/test/libsolidity/semanticTests/strings/constant_string_literal.sol new file mode 100644 index 0000000000..9c112c1faa --- /dev/null +++ b/test/libsolidity/semanticTests/strings/constant_string_literal.sol @@ -0,0 +1,25 @@ +contract Test { + bytes32 constant public b = "abcdefghijklmnopq"; + string constant public x = "abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca"; + + constructor() { + string memory xx = x; + bytes32 bb = b; + } + function getB() public returns (bytes32) { return b; } + function getX() public returns (string memory) { return x; } + function getX2() public returns (string memory r) { r = x; } + function unused() public returns (uint) { + "unusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunused"; + return 2; + } +} +// ==== +// compileViaYul: also +// ---- +// b() -> 0x6162636465666768696a6b6c6d6e6f7071000000000000000000000000000000 +// x() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096 +// getB() -> 0x6162636465666768696a6b6c6d6e6f7071000000000000000000000000000000 +// getX() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096 +// getX2() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096 +// unused() -> 2 diff --git a/test/libsolidity/semanticTests/strings/return_string.sol b/test/libsolidity/semanticTests/strings/return_string.sol new file mode 100644 index 0000000000..f221a5e156 --- /dev/null +++ b/test/libsolidity/semanticTests/strings/return_string.sol @@ -0,0 +1,20 @@ +contract Main { + string public s; + function set(string calldata _s) external { + s = _s; + } + function get1() public returns (string memory r) { + return s; + } + function get2() public returns (string memory r) { + r = s; + } +} +// ==== +// compileToEwasm: also +// compileViaYul: also +// ---- +// set(string): 0x20, 5, "Julia" -> +// get1() -> 0x20, 5, "Julia" +// get2() -> 0x20, 5, "Julia" +// s() -> 0x20, 5, "Julia" diff --git a/test/libsolidity/semanticTests/structs/packed_storage_structs_delete.sol b/test/libsolidity/semanticTests/structs/packed_storage_structs_delete.sol new file mode 100644 index 0000000000..8d4931554d --- /dev/null +++ b/test/libsolidity/semanticTests/structs/packed_storage_structs_delete.sol @@ -0,0 +1,27 @@ +contract C { + struct str { uint8 a; uint16 b; uint8 c; } + uint8 x; + uint16 y; + str data; + function test() public returns (uint) { + x = 1; + y = 2; + data.a = 2; + data.b = 0xabcd; + data.c = 0xfa; + if (x != 1 || y != 2 || data.a != 2 || data.b != 0xabcd || data.c != 0xfa) + return 2; + delete y; + delete data.b; + if (x != 1 || y != 0 || data.a != 2 || data.b != 0 || data.c != 0xfa) + return 3; + delete x; + delete data; + return 1; + } +} +// ==== +// compileViaYul: also +// ---- +// test() -> 1 +// storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/variables/storing_invalid_boolean.sol b/test/libsolidity/semanticTests/variables/storing_invalid_boolean.sol new file mode 100644 index 0000000000..930ded40bf --- /dev/null +++ b/test/libsolidity/semanticTests/variables/storing_invalid_boolean.sol @@ -0,0 +1,35 @@ +contract C { + event Ev(bool); + bool public perm; + function set() public returns(uint) { + bool tmp; + assembly { + tmp := 5 + } + perm = tmp; + return 1; + } + function ret() public returns(bool) { + bool tmp; + assembly { + tmp := 5 + } + return tmp; + } + function ev() public returns(uint) { + bool tmp; + assembly { + tmp := 5 + } + emit Ev(tmp); + return 1; + } +} +// ==== +// compileViaYul: also +// ---- +// set() -> 1 +// perm() -> true +// ret() -> true +// ev() -> 1 +// ~ emit Ev(bool): true From bd399e37e3cd2224c9403b6c7ce4ab6f7c990817 Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Tue, 30 Nov 2021 00:12:52 +0530 Subject: [PATCH 0153/1748] restoring the RTD section. Downloads section to still be above versions section --- docs/_templates/versions.html | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/_templates/versions.html b/docs/_templates/versions.html index 9168179dfd..a2432e3703 100644 --- a/docs/_templates/versions.html +++ b/docs/_templates/versions.html @@ -1,11 +1,7 @@ {# Add rst-badge after rst-versions for small badge style. #}
- {% for type, url in downloads %} - {% if type == 'PDF' %} - {{ type }} - {% endif %} - {% endfor %} + RTD From 310f74302d893243a0abc03352654f8e21157be7 Mon Sep 17 00:00:00 2001 From: Dallon Asnes Date: Mon, 29 Nov 2021 15:31:52 -0600 Subject: [PATCH 0154/1748] Add fixed size type details to encodePacked doc --- docs/abi-spec.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 6f50c70d9e..02e5f8b2a4 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -749,7 +749,7 @@ Non-standard Packed Mode Through ``abi.encodePacked()``, Solidity supports a non-standard packed mode where: -- types shorter than 32 bytes are neither zero padded nor sign extended and +- types shorter than 32 bytes are concatenated directly, without padding or sign extension - dynamic types are encoded in-place and without the length. - array elements are padded, but still encoded in-place From 86ce5f1da50e7de9c4d0649273637adda10f46b9 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 29 Nov 2021 21:19:41 +0100 Subject: [PATCH 0155/1748] Use LineColumn type. --- liblangutil/CharStream.cpp | 4 ++-- liblangutil/CharStream.h | 3 ++- liblangutil/SourceLocation.h | 19 +++++++++++++++++++ liblangutil/SourceReferenceExtractor.h | 9 --------- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/liblangutil/CharStream.cpp b/liblangutil/CharStream.cpp index 3b30bad776..96a6aebe29 100644 --- a/liblangutil/CharStream.cpp +++ b/liblangutil/CharStream.cpp @@ -100,7 +100,7 @@ string CharStream::lineAtPosition(int _position) const return line; } -tuple CharStream::translatePositionToLineColumn(int _position) const +LineColumn CharStream::translatePositionToLineColumn(int _position) const { using size_type = string::size_type; using diff_type = string::difference_type; @@ -114,7 +114,7 @@ tuple CharStream::translatePositionToLineColumn(int _position) const lineStart = m_source.rfind('\n', searchPosition - 1); lineStart = lineStart == string::npos ? 0 : lineStart + 1; } - return tuple(lineNumber, searchPosition - lineStart); + return LineColumn{lineNumber, static_cast(searchPosition - lineStart)}; } string_view CharStream::text(SourceLocation const& _location) const diff --git a/liblangutil/CharStream.h b/liblangutil/CharStream.h index 761cece316..2e5d79d932 100644 --- a/liblangutil/CharStream.h +++ b/liblangutil/CharStream.h @@ -59,6 +59,7 @@ namespace solidity::langutil { struct SourceLocation; +struct LineColumn; /** * Bidirectional stream of characters. @@ -97,7 +98,7 @@ class CharStream /// Functions that help pretty-printing parse errors /// Do only use in error cases, they are quite expensive. std::string lineAtPosition(int _position) const; - std::tuple translatePositionToLineColumn(int _position) const; + LineColumn translatePositionToLineColumn(int _position) const; ///@} /// Tests whether or not given octet sequence is present at the current position in stream. diff --git a/liblangutil/SourceLocation.h b/liblangutil/SourceLocation.h index ea9958933d..ddb4575356 100644 --- a/liblangutil/SourceLocation.h +++ b/liblangutil/SourceLocation.h @@ -119,4 +119,23 @@ SourceLocation parseSourceLocation( /// Stream output for Location (used e.g. in boost exceptions). std::ostream& operator<<(std::ostream& _out, SourceLocation const& _location); + +/** + * Alternative, line-column-based representation for source locations. + * Both line and column are zero-based. + * If used as a range, the second location is considered exclusive. + * Negative values are invalid. + */ +struct LineColumn +{ + /// Line value, can be between zero and number of `\n` characters in the source file. + int line = -1; + /// Column value, can be between zero and number of characters in the line (inclusive). + int column = -1; + + LineColumn() = default; + explicit LineColumn(int _line, int _column): line(_line), column(_column) {} +}; + + } diff --git a/liblangutil/SourceReferenceExtractor.h b/liblangutil/SourceReferenceExtractor.h index 6aeb6065e1..3b418fcfa2 100644 --- a/liblangutil/SourceReferenceExtractor.h +++ b/liblangutil/SourceReferenceExtractor.h @@ -30,15 +30,6 @@ namespace solidity::langutil class CharStreamProvider; -struct LineColumn -{ - int line = {-1}; - int column = {-1}; - - LineColumn() = default; - LineColumn(std::tuple const& _t): line{std::get<0>(_t)}, column{std::get<1>(_t)} {} -}; - struct SourceReference { std::string message; ///< A message that relates to this source reference (such as a warning, info or an error message). From a0aacb91a6d42a2220081cfaaab17ddaf569f354 Mon Sep 17 00:00:00 2001 From: Dallon Asnes Date: Mon, 29 Nov 2021 23:43:28 -0600 Subject: [PATCH 0156/1748] Fix cl test script on macOS --- test/cmdlineTests.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 4f9d41384b..87442c6067 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -54,7 +54,13 @@ do shift ;; *) - matching_tests=$(find . -mindepth 1 -maxdepth 1 -type d -name "$1" | cut --characters 3- | sort) + if [[ "$OSTYPE" == "darwin"* ]] + then + matching_tests=$(find . -mindepth 1 -maxdepth 1 -type d -name "$1" | cut -c 3- | sort) + else + matching_tests=$(find . -mindepth 1 -maxdepth 1 -type d -name "$1" | cut --characters 3- | sort) + fi + if [[ $matching_tests == "" ]] then From 70e925dbfc98a6e8c519f0095d4077fa28fda2c5 Mon Sep 17 00:00:00 2001 From: Dallon Asnes <30935722+dallonasnes@users.noreply.github.com> Date: Tue, 30 Nov 2021 10:07:50 -0600 Subject: [PATCH 0157/1748] Update test/cmdlineTests.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kamil Śliwak --- test/cmdlineTests.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 87442c6067..f9a26cb46b 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -54,12 +54,7 @@ do shift ;; *) - if [[ "$OSTYPE" == "darwin"* ]] - then - matching_tests=$(find . -mindepth 1 -maxdepth 1 -type d -name "$1" | cut -c 3- | sort) - else - matching_tests=$(find . -mindepth 1 -maxdepth 1 -type d -name "$1" | cut --characters 3- | sort) - fi + matching_tests=$(find . -mindepth 1 -maxdepth 1 -type d -name "$1" | cut -c 3- | sort) if [[ $matching_tests == "" ]] From bd193ae8401066bce6fbc3cede100f693b17922b Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 1 Dec 2021 12:46:02 +0100 Subject: [PATCH 0158/1748] Fix whitespace problem. --- test/cmdlineTests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index f9a26cb46b..d33dd208c1 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -55,7 +55,6 @@ do ;; *) matching_tests=$(find . -mindepth 1 -maxdepth 1 -type d -name "$1" | cut -c 3- | sort) - if [[ $matching_tests == "" ]] then From b6bd85202c0e5e6bae0dcc71b9ebcfea17de5f9a Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 1 Dec 2021 12:30:36 +0100 Subject: [PATCH 0159/1748] Accessors for exceptions. --- liblangutil/Exceptions.cpp | 10 ++++++++++ liblangutil/Exceptions.h | 5 ++++- libsolidity/interface/StandardCompiler.cpp | 2 +- libsolutil/Exceptions.h | 2 -- test/libsolidity/AnalysisFramework.cpp | 2 +- test/libsolidity/SyntaxTest.cpp | 5 +++-- test/libyul/SyntaxTest.cpp | 2 +- 7 files changed, 20 insertions(+), 8 deletions(-) diff --git a/liblangutil/Exceptions.cpp b/liblangutil/Exceptions.cpp index a410a98635..2595c7755c 100644 --- a/liblangutil/Exceptions.cpp +++ b/liblangutil/Exceptions.cpp @@ -75,6 +75,16 @@ Error::Error( *this << util::errinfo_comment(_description); } +SourceLocation const* Error::sourceLocation() const noexcept +{ + return boost::get_error_info(*this); +} + +SecondarySourceLocation const* Error::secondarySourceLocation() const noexcept +{ + return boost::get_error_info(*this); +} + optional Error::severityFromString(string _input) { boost::algorithm::to_lower(_input); diff --git a/liblangutil/Exceptions.h b/liblangutil/Exceptions.h index 0c8f03cb94..10fca80293 100644 --- a/liblangutil/Exceptions.h +++ b/liblangutil/Exceptions.h @@ -197,6 +197,9 @@ class Error: virtual public util::Exception Type type() const { return m_type; } std::string const& typeName() const { return m_typeName; } + SourceLocation const* sourceLocation() const noexcept; + SecondarySourceLocation const* secondarySourceLocation() const noexcept; + /// helper functions static Error const* containsErrorOfType(ErrorList const& _list, Error::Type _type) { @@ -206,7 +209,7 @@ class Error: virtual public util::Exception return nullptr; } - static Severity errorSeverity(Type _type) + static constexpr Severity errorSeverity(Type _type) { if (_type == Type::Info) return Severity::Info; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index da28cf29f2..39ed7c10fb 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -129,7 +129,7 @@ Json::Value formatErrorWithException( _charStreamProvider ); - if (string const* description = boost::get_error_info(_exception)) + if (string const* description = _exception.comment()) message = ((_message.length() > 0) ? (_message + ":") : "") + *description; else message = _message; diff --git a/libsolutil/Exceptions.h b/libsolutil/Exceptions.h index d83d8004b4..9d351a28d2 100644 --- a/libsolutil/Exceptions.h +++ b/libsolutil/Exceptions.h @@ -39,8 +39,6 @@ struct Exception: virtual std::exception, virtual boost::exception /// @returns the errinfo_comment of this exception. std::string const* comment() const noexcept; - -private: }; /// Throws an exception with a given description and extra information about the location the diff --git a/test/libsolidity/AnalysisFramework.cpp b/test/libsolidity/AnalysisFramework.cpp index 84c7a5e0bd..5dce2211f9 100644 --- a/test/libsolidity/AnalysisFramework.cpp +++ b/test/libsolidity/AnalysisFramework.cpp @@ -100,7 +100,7 @@ ErrorList AnalysisFramework::filterErrors(ErrorList const& _errorList, bool _inc for (auto const& messagePrefix: m_messagesToCut) if (currentError->comment()->find(messagePrefix) == 0) { - SourceLocation const* location = boost::get_error_info(*currentError); + SourceLocation const* location = currentError->sourceLocation(); // sufficient for now, but in future we might clone the error completely, including the secondary location newError = make_shared( currentError->errorId(), diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp index 4998b628b3..d3e5124508 100644 --- a/test/libsolidity/SyntaxTest.cpp +++ b/test/libsolidity/SyntaxTest.cpp @@ -118,9 +118,10 @@ void SyntaxTest::filterObtainedErrors() { for (auto const& currentError: filterErrors(compiler().errors(), true)) { - int locationStart = -1, locationEnd = -1; + int locationStart = -1; + int locationEnd = -1; string sourceName; - if (auto location = boost::get_error_info(*currentError)) + if (SourceLocation const* location = currentError->sourceLocation()) { solAssert(location->sourceName, ""); sourceName = *location->sourceName; diff --git a/test/libyul/SyntaxTest.cpp b/test/libyul/SyntaxTest.cpp index 4668773e93..8ab5bb9530 100644 --- a/test/libyul/SyntaxTest.cpp +++ b/test/libyul/SyntaxTest.cpp @@ -54,7 +54,7 @@ void SyntaxTest::parseAndAnalyze() int locationStart = -1; int locationEnd = -1; - if (auto location = boost::get_error_info(*error)) + if (SourceLocation const* location = error->sourceLocation()) { locationStart = location->start; locationEnd = location->end; From 264b7bd85739deb1baff7678a7ea34130b988d88 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 1 Dec 2021 12:20:09 +0100 Subject: [PATCH 0160/1748] LineColumn handling for CharStream. --- liblangutil/CharStream.cpp | 29 +++++++++++ liblangutil/CharStream.h | 7 +++ test/liblangutil/CharStream.cpp | 85 ++++++++++++++++++++++++++++++++- 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/liblangutil/CharStream.cpp b/liblangutil/CharStream.cpp index 96a6aebe29..6ecd85bfed 100644 --- a/liblangutil/CharStream.cpp +++ b/liblangutil/CharStream.cpp @@ -144,3 +144,32 @@ string CharStream::singleLineSnippet(string const& _sourceCode, SourceLocation c return cut; } + +optional CharStream::translateLineColumnToPosition(LineColumn const& _lineColumn) const +{ + return translateLineColumnToPosition(m_source, _lineColumn); +} + +optional CharStream::translateLineColumnToPosition(std::string const& _text, LineColumn const& _input) +{ + if (_input.line < 0) + return nullopt; + + size_t offset = 0; + for (int i = 0; i < _input.line; i++) + { + offset = _text.find('\n', offset); + if (offset == _text.npos) + return nullopt; + offset++; // Skip linefeed. + } + + size_t endOfLine = _text.find('\n', offset); + if (endOfLine == string::npos) + endOfLine = _text.size(); + + if (offset + static_cast(_input.column) > endOfLine) + return nullopt; + return offset + static_cast(_input.column); +} + diff --git a/liblangutil/CharStream.h b/liblangutil/CharStream.h index 2e5d79d932..08f86129b2 100644 --- a/liblangutil/CharStream.h +++ b/liblangutil/CharStream.h @@ -51,6 +51,7 @@ #pragma once #include +#include #include #include #include @@ -101,6 +102,12 @@ class CharStream LineColumn translatePositionToLineColumn(int _position) const; ///@} + /// Translates a line:column to the absolute position. + std::optional translateLineColumnToPosition(LineColumn const& _lineColumn) const; + + /// Translates a line:column to the absolute position for the given input text. + static std::optional translateLineColumnToPosition(std::string const& _text, LineColumn const& _input); + /// Tests whether or not given octet sequence is present at the current position in stream. /// @returns true if the sequence could be found, false otherwise. bool prefixMatch(std::string_view _sequence) diff --git a/test/liblangutil/CharStream.cpp b/test/liblangutil/CharStream.cpp index 9321b14e0d..766a700986 100644 --- a/test/liblangutil/CharStream.cpp +++ b/test/liblangutil/CharStream.cpp @@ -28,6 +28,33 @@ #include +using namespace std; +using namespace solidity::test; + +namespace boost::test_tools::tt_detail +{ + +template<> +struct print_log_value> +{ + void operator()(std::ostream& _out, std::optional const& _value) const + { + _out << (_value ? to_string(*_value) : "[nullopt]"); + } +}; + +template<> +struct print_log_value +{ + void operator()(std::ostream& _out, nullopt_t const&) const + { + _out << "[nullopt]"; + } +}; + +} // namespace boost::test_tools::tt_detail + + namespace solidity::langutil::test { @@ -48,6 +75,62 @@ BOOST_AUTO_TEST_CASE(test_fail) ); } +namespace +{ +std::optional toPosition(int _line, int _column, string const& _text) +{ + return CharStream{_text, "source"}.translateLineColumnToPosition( + LineColumn{_line, _column} + ); +} + +} + +BOOST_AUTO_TEST_CASE(translateLineColumnToPosition) +{ + BOOST_CHECK_EQUAL(toPosition(-1, 0, "ABC"), nullopt); + BOOST_CHECK_EQUAL(toPosition(0, -1, "ABC"), nullopt); + + BOOST_CHECK_EQUAL(toPosition(0, 0, ""), 0); + BOOST_CHECK_EQUAL(toPosition(1, 0, ""), nullopt); + BOOST_CHECK_EQUAL(toPosition(0, 1, ""), nullopt); + + // With last line containing no LF + BOOST_CHECK_EQUAL(toPosition(0, 0, "ABC"), 0); + BOOST_CHECK_EQUAL(toPosition(0, 1, "ABC"), 1); + BOOST_CHECK_EQUAL(toPosition(0, 2, "ABC"), 2); + BOOST_CHECK_EQUAL(toPosition(0, 3, "ABC"), 3); + BOOST_CHECK_EQUAL(toPosition(0, 4, "ABC"), nullopt); + BOOST_CHECK_EQUAL(toPosition(1, 0, "ABC"), nullopt); + + BOOST_CHECK_EQUAL(toPosition(0, 3, "ABC\nDEF"), 3); + BOOST_CHECK_EQUAL(toPosition(0, 4, "ABC\nDEF"), nullopt); + BOOST_CHECK_EQUAL(toPosition(1, 0, "ABC\nDEF"), 4); + BOOST_CHECK_EQUAL(toPosition(1, 1, "ABC\nDEF"), 5); + BOOST_CHECK_EQUAL(toPosition(1, 2, "ABC\nDEF"), 6); + BOOST_CHECK_EQUAL(toPosition(1, 3, "ABC\nDEF"), 7); + BOOST_CHECK_EQUAL(toPosition(1, 4, "ABC\nDEF"), nullopt); + BOOST_CHECK_EQUAL(toPosition(2, 0, "ABC\nDEF"), nullopt); + BOOST_CHECK_EQUAL(toPosition(2, 1, "ABC\nDEF"), nullopt); + + // With last line containing LF + BOOST_CHECK_EQUAL(toPosition(0, 0, "ABC\nDEF\n"), 0); + BOOST_CHECK_EQUAL(toPosition(0, 1, "ABC\nDEF\n"), 1); + BOOST_CHECK_EQUAL(toPosition(0, 2, "ABC\nDEF\n"), 2); + + BOOST_CHECK_EQUAL(toPosition(1, 0, "ABC\nDEF\n"), 4); + BOOST_CHECK_EQUAL(toPosition(1, 1, "ABC\nDEF\n"), 5); + BOOST_CHECK_EQUAL(toPosition(1, 2, "ABC\nDEF\n"), 6); + BOOST_CHECK_EQUAL(toPosition(1, 3, "ABC\nDEF\n"), 7); + BOOST_CHECK_EQUAL(toPosition(1, 4, "ABC\nDEF\n"), nullopt); + BOOST_CHECK_EQUAL(toPosition(2, 0, "ABC\nDEF\n"), 8); + BOOST_CHECK_EQUAL(toPosition(2, 1, "ABC\nDEF\n"), nullopt); + + BOOST_CHECK_EQUAL(toPosition(2, 0, "ABC\nDEF\nGHI\n"), 8); + BOOST_CHECK_EQUAL(toPosition(2, 1, "ABC\nDEF\nGHI\n"), 9); + BOOST_CHECK_EQUAL(toPosition(2, 2, "ABC\nDEF\nGHI\n"), 10); +} + BOOST_AUTO_TEST_SUITE_END() -} // end namespaces +} From d56fb3afffd23dfac656a14d2c3c60c7db841f16 Mon Sep 17 00:00:00 2001 From: Tynan Richards Date: Wed, 24 Nov 2021 14:39:14 +0100 Subject: [PATCH 0161/1748] Fix ExpressionSplitter example Fix error (0x123 and 0x456 were swapped) and split constants into expressions --- docs/internals/optimizer.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index d75eca4198..ccb72b9396 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -521,7 +521,7 @@ ExpressionSplitter The expression splitter turns expressions like ``add(mload(0x123), mul(mload(0x456), 0x20))`` into a sequence of declarations of unique variables that are assigned sub-expressions -of that expression so that each function call has only variables or literals +of that expression so that each function call has only variables as arguments. The above would be transformed into @@ -529,10 +529,13 @@ The above would be transformed into .. code-block:: yul { - let _1 := mload(0x123) - let _2 := mul(_1, 0x20) - let _3 := mload(0x456) - let z := add(_3, _2) + let _1 = 0x20 + let _2 = 0x456 + let _3 = mload(_2) + let _4 = mul(_3, _1) + let _5 = 0x123 + let _6 = mload(_5) + let z = add(_6, _4) } Note that this transformation does not change the order of opcodes or function calls. @@ -543,7 +546,7 @@ this "outlining" of the inner expressions in all cases. We can sidestep this lim The final program should be in a form such that (with the exception of loop conditions) function calls cannot appear nested inside expressions -and all function call arguments have to be literals or variables. +and all function call arguments have to be variables. The benefits of this form are that it is much easier to re-order the sequence of opcodes and it is also easier to perform function call inlining. Furthermore, it is simpler From 829fe6615ba601de8f605941251b2996aad6032a Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 1 Dec 2021 16:23:26 +0100 Subject: [PATCH 0162/1748] Fix Yul example. --- docs/internals/optimizer.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index ccb72b9396..19bca791e8 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -529,13 +529,13 @@ The above would be transformed into .. code-block:: yul { - let _1 = 0x20 - let _2 = 0x456 - let _3 = mload(_2) - let _4 = mul(_3, _1) - let _5 = 0x123 - let _6 = mload(_5) - let z = add(_6, _4) + let _1 := 0x20 + let _2 := 0x456 + let _3 := mload(_2) + let _4 := mul(_3, _1) + let _5 := 0x123 + let _6 := mload(_5) + let z := add(_6, _4) } Note that this transformation does not change the order of opcodes or function calls. From d9a4020a92db3fdc92163fa1bdb8b46ce13fae86 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 1 Dec 2021 12:31:21 +0100 Subject: [PATCH 0163/1748] Function to read a number of bytes from an input stream. --- libsolutil/CommonIO.cpp | 11 +++++++++++ libsolutil/CommonIO.h | 4 ++++ test/libsolutil/CommonIO.cpp | 9 +++++++++ 3 files changed, 24 insertions(+) diff --git a/libsolutil/CommonIO.cpp b/libsolutil/CommonIO.cpp index 9da5b2422a..6089f4db66 100644 --- a/libsolutil/CommonIO.cpp +++ b/libsolutil/CommonIO.cpp @@ -79,6 +79,17 @@ string solidity::util::readUntilEnd(istream& _stdin) return ss.str(); } +string solidity::util::readBytes(istream& _input, size_t _length) +{ + string output; + output.resize(_length); + _input.read(output.data(), static_cast(_length)); + // If read() reads fewer bytes it sets failbit in addition to eofbit. + if (_input.fail()) + output.resize(static_cast(_input.gcount())); + return output; +} + #if defined(_WIN32) class DisableConsoleBuffering { diff --git a/libsolutil/CommonIO.h b/libsolutil/CommonIO.h index ab0000f868..e6cd0c1616 100644 --- a/libsolutil/CommonIO.h +++ b/libsolutil/CommonIO.h @@ -57,6 +57,10 @@ std::string readFileAsString(boost::filesystem::path const& _file); /// Retrieves and returns the whole content of the specified input stream (until EOF). std::string readUntilEnd(std::istream& _stdin); +/// Tries to read exactly @a _length bytes from @a _input. +/// Returns a string containing as much data as has been read. +std::string readBytes(std::istream& _input, size_t _length); + /// Retrieves and returns a character from standard input (without waiting for EOL). int readStandardInputChar(); diff --git a/test/libsolutil/CommonIO.cpp b/test/libsolutil/CommonIO.cpp index ce1a24a414..8b8c3d3263 100644 --- a/test/libsolutil/CommonIO.cpp +++ b/test/libsolutil/CommonIO.cpp @@ -90,6 +90,15 @@ BOOST_AUTO_TEST_CASE(readUntilEnd_empty) BOOST_TEST(readUntilEnd(inputStream) == ""); } +BOOST_AUTO_TEST_CASE(readBytes_past_end) +{ + istringstream inputStream("abc"); + BOOST_CHECK_EQUAL(readBytes(inputStream, 0), ""); + BOOST_CHECK_EQUAL(readBytes(inputStream, 1), "a"); + BOOST_CHECK_EQUAL(readBytes(inputStream, 20), "bc"); + BOOST_CHECK_EQUAL(readBytes(inputStream, 20), ""); +} + BOOST_AUTO_TEST_SUITE_END() } // namespace solidity::util::test From 105de2561acda08ae4220c63f21093e1a30c032e Mon Sep 17 00:00:00 2001 From: Saska Karsi <44523813+saska@users.noreply.github.com> Date: Fri, 3 Dec 2021 01:11:04 +0200 Subject: [PATCH 0164/1748] rm trailing comma in style-guide.rst example --- 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 9e0fba5f66..64e76526f5 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -747,7 +747,7 @@ Yes: function thisFunctionNameIsReallyLong( address x, address y, - address z, + address z ) public onlyOwner From 16535aae3272e676a140ea94e3f2a757a2ee20ec Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 1 Dec 2021 17:38:23 +0100 Subject: [PATCH 0165/1748] Fix ICE when unsafe targets are solved more than once and the cex is different --- Changelog.md | 1 + libsolidity/formal/CHC.cpp | 2 - .../smtCheckerTests/imports/ExtCall.sol | 42 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/imports/ExtCall.sol diff --git a/Changelog.md b/Changelog.md index b3af54d047..e24cb24628 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: Bugfixes: * Code Generator: Fix a crash when using ``@use-src`` and compiling from Yul to ewasm. + * SMTChecker: Fix internal error when an unsafe target is solved more than once and the counterexample messages are different. ### 0.8.10 (2021-11-09) diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 76a5ded998..0edfc27fff 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -972,8 +972,6 @@ void CHC::resetSourceAnalysis() { SMTEncoder::resetSourceAnalysis(); - m_safeTargets.clear(); - m_unsafeTargets.clear(); m_unprovedTargets.clear(); m_invariants.clear(); m_functionTargetIds.clear(); diff --git a/test/libsolidity/smtCheckerTests/imports/ExtCall.sol b/test/libsolidity/smtCheckerTests/imports/ExtCall.sol new file mode 100644 index 0000000000..047148a90c --- /dev/null +++ b/test/libsolidity/smtCheckerTests/imports/ExtCall.sol @@ -0,0 +1,42 @@ +==== Source: ExtCall.sol ==== +interface Unknown { + function callme() external; +} + +contract ExtCall { + uint x; + + bool lock; + modifier mutex { + require(!lock); + lock = true; + _; + lock = false; + } + + function setX(uint y) mutex public { + x = y; + } + + function xMut(Unknown u) public { + uint x_prev = x; + u.callme(); + assert(x_prev == x); + } +} +==== Source: ExtCall.t.sol ==== +import "ExtCall.sol"; + +contract ExtCallTest { + ExtCall call; + + function setUp() public { + call = new ExtCall(); + } +} +// ==== +// SMTEngine: all +// SMTIgnoreCex: yes +// ---- +// Warning 6328: (ExtCall.sol:362-381): CHC: Assertion violation happens here. +// Warning 4588: (ExtCall.t.sol:110-123): Assertion checker does not yet implement this type of function call. From a4fbc607c65ed63484e130dea58377b70f573bbe Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Wed, 10 Nov 2021 17:46:36 +0530 Subject: [PATCH 0166/1748] Issue 11610 : Replced typeError with fataTypeError in lines 390 and 406. Test file added in test/libsolidity/syntaxTests/calldata_struct_argument_with_internal_type_inside.sol Issue : 11610 : Test cases updated, Changelog.md file updated to include change on 0.8.11 --- Changelog.md | 2 ++ libsolidity/analysis/TypeChecker.cpp | 4 ++-- ...s_taking_internal_types_nested_struct_with_mapping.sol | 1 - ...unctions_taking_internal_types_struct_with_mapping.sol | 1 - test/libsolidity/syntaxTests/array/function_mapping.sol | 1 - .../constructor/constructor_mapping_memory.sol | 1 - ...ata_struct_argument_with_internal_data_type_inside.sol | 8 ++++++++ ...ruct_array_argument_with_internal_data_type_inside.sol | 8 ++++++++ ...internal_data_type_inside_as_constructor_parameter.sol | 8 ++++++++ .../structs/calldata_struct_mapping_function.sol | 1 - .../recursion/recursive_struct_nested_mapping_memory.sol | 1 - ...apping_array_data_location_function_param_external.sol | 1 - .../mapping_data_location_function_param_external.sol | 1 - .../mapping_data_location_function_param_public.sol | 1 - .../types/mapping/mapping_function_calldata.sol | 1 - .../types/mapping/mapping_return_public_memory.sol | 1 - .../types/mapping/mapping_struct_data_location_memory.sol | 1 - .../mapping_struct_recusrive_data_location_memory.sol | 1 - 18 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 test/libsolidity/syntaxTests/functionCalls/calldata_struct_argument_with_internal_data_type_inside.sol create mode 100644 test/libsolidity/syntaxTests/functionCalls/calldata_struct_array_argument_with_internal_data_type_inside.sol create mode 100644 test/libsolidity/syntaxTests/functionCalls/calldata_struct_array_argument_with_internal_data_type_inside_as_constructor_parameter.sol diff --git a/Changelog.md b/Changelog.md index e24cb24628..9ecf2ce556 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,8 @@ Compiler Features: Bugfixes: * Code Generator: Fix a crash when using ``@use-src`` and compiling from Yul to ewasm. * SMTChecker: Fix internal error when an unsafe target is solved more than once and the counterexample messages are different. + * Fix internal error when a function has a calldata struct argument with an internal type inside. + ### 0.8.10 (2021-11-09) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 05fdc489bb..5cc208d698 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -387,7 +387,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) _var.referenceLocation() == VariableDeclaration::Location::Storage && !m_currentContract->abstract() ) - m_errorReporter.typeError( + m_errorReporter.fatalTypeError( 3644_error, _var.location(), "This parameter has a type that can only be used internally. " @@ -403,7 +403,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) solAssert(!message.empty(), "Expected detailed error message!"); if (_function.isConstructor()) message += " You can make the contract abstract to avoid this problem."; - m_errorReporter.typeError(4103_error, _var.location(), message); + m_errorReporter.fatalTypeError(4103_error, _var.location(), message); } else if ( !useABICoderV2() && diff --git a/test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_nested_struct_with_mapping.sol b/test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_nested_struct_with_mapping.sol index 78660bdae4..9c82812e96 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_nested_struct_with_mapping.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_nested_struct_with_mapping.sol @@ -7,4 +7,3 @@ contract C { } // ---- // TypeError 4103: (132-140): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (132-140): Type struct C.S is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_struct_with_mapping.sol b/test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_struct_with_mapping.sol index 297f809fd6..144962c2a0 100644 --- a/test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_struct_with_mapping.sol +++ b/test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_struct_with_mapping.sol @@ -6,4 +6,3 @@ contract C { } // ---- // TypeError 4103: (105-113): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (105-113): Type struct C.S is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/array/function_mapping.sol b/test/libsolidity/syntaxTests/array/function_mapping.sol index 531ef6c7b6..3f64c081c3 100644 --- a/test/libsolidity/syntaxTests/array/function_mapping.sol +++ b/test/libsolidity/syntaxTests/array/function_mapping.sol @@ -5,4 +5,3 @@ contract Test { } // ---- // TypeError 4103: (66-98): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (66-98): Type mapping(uint256 => uint256)[] is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/constructor/constructor_mapping_memory.sol b/test/libsolidity/syntaxTests/constructor/constructor_mapping_memory.sol index 266a440d63..b9e0ed801d 100644 --- a/test/libsolidity/syntaxTests/constructor/constructor_mapping_memory.sol +++ b/test/libsolidity/syntaxTests/constructor/constructor_mapping_memory.sol @@ -3,4 +3,3 @@ contract A { } // ---- // TypeError 4103: (29-59): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. You can make the contract abstract to avoid this problem. -// TypeError 4061: (29-59): Type mapping(uint256 => uint256) is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/functionCalls/calldata_struct_argument_with_internal_data_type_inside.sol b/test/libsolidity/syntaxTests/functionCalls/calldata_struct_argument_with_internal_data_type_inside.sol new file mode 100644 index 0000000000..729dba7786 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionCalls/calldata_struct_argument_with_internal_data_type_inside.sol @@ -0,0 +1,8 @@ +contract C { + struct S { + function() a; + } + function f(S calldata) public {} +} +// ---- +// TypeError 4103: (56-66): Internal type is not allowed for public or external functions. \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/functionCalls/calldata_struct_array_argument_with_internal_data_type_inside.sol b/test/libsolidity/syntaxTests/functionCalls/calldata_struct_array_argument_with_internal_data_type_inside.sol new file mode 100644 index 0000000000..f618934e3d --- /dev/null +++ b/test/libsolidity/syntaxTests/functionCalls/calldata_struct_array_argument_with_internal_data_type_inside.sol @@ -0,0 +1,8 @@ +contract C { + struct S { + function() a; + } + function f(S[2] calldata) public {} +} +// ---- +// TypeError 4103: (56-69): Internal type is not allowed for public or external functions. diff --git a/test/libsolidity/syntaxTests/functionCalls/calldata_struct_array_argument_with_internal_data_type_inside_as_constructor_parameter.sol b/test/libsolidity/syntaxTests/functionCalls/calldata_struct_array_argument_with_internal_data_type_inside_as_constructor_parameter.sol new file mode 100644 index 0000000000..796b0fc586 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionCalls/calldata_struct_array_argument_with_internal_data_type_inside_as_constructor_parameter.sol @@ -0,0 +1,8 @@ +contract C { + struct S { + function() a; + } + constructor (S[2] storage) public {} +} +// ---- +// TypeError 3644: (58-70): This parameter has a type that can only be used internally. You can make the contract abstract to avoid this problem. diff --git a/test/libsolidity/syntaxTests/structs/calldata_struct_mapping_function.sol b/test/libsolidity/syntaxTests/structs/calldata_struct_mapping_function.sol index dcdbad68bc..9ff30c6ec0 100644 --- a/test/libsolidity/syntaxTests/structs/calldata_struct_mapping_function.sol +++ b/test/libsolidity/syntaxTests/structs/calldata_struct_mapping_function.sol @@ -12,4 +12,3 @@ contract test { } // ---- // TypeError 4103: (155-167): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (155-167): Type struct test.S is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/structs/recursion/recursive_struct_nested_mapping_memory.sol b/test/libsolidity/syntaxTests/structs/recursion/recursive_struct_nested_mapping_memory.sol index 6009ee94d2..c8708e3e0d 100644 --- a/test/libsolidity/syntaxTests/structs/recursion/recursive_struct_nested_mapping_memory.sol +++ b/test/libsolidity/syntaxTests/structs/recursion/recursive_struct_nested_mapping_memory.sol @@ -7,4 +7,3 @@ library a { } // ---- // TypeError 4103: (149-157): Recursive structs can only be passed as storage pointers to libraries, not as memory objects to contract functions. -// TypeError 4061: (149-157): Type struct a.b is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_array_data_location_function_param_external.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_array_data_location_function_param_external.sol index 72c2a12a85..f959394d1f 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_array_data_location_function_param_external.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_array_data_location_function_param_external.sol @@ -3,4 +3,3 @@ contract c { } // ---- // TypeError 4103: (29-61): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (29-61): Type mapping(uint256 => uint256)[] is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol index 3bc5d7a29c..1281e4b514 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol @@ -3,4 +3,3 @@ contract c { } // ---- // TypeError 4103: (29-59): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (29-59): Type mapping(uint256 => uint256) is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol index f8a6666750..667c0b1013 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol @@ -3,4 +3,3 @@ contract c { } // ---- // TypeError 4103: (29-57): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (29-57): Type mapping(uint256 => uint256) is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_function_calldata.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_function_calldata.sol index 1301a03c3c..8b780ea8d4 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_function_calldata.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_function_calldata.sol @@ -9,4 +9,3 @@ contract test { } // ---- // TypeError 4103: (121-133): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (121-133): Type struct test.S is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol index 4d06bad5a4..6594401c6e 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol @@ -4,4 +4,3 @@ contract C { } // ---- // TypeError 4103: (51-79): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (51-79): Type mapping(uint256 => uint256) is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_struct_data_location_memory.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_struct_data_location_memory.sol index 8208c2e2e8..399f7c6ae4 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_struct_data_location_memory.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_struct_data_location_memory.sol @@ -5,4 +5,3 @@ contract C { } // ---- // TypeError 4103: (104-112): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (104-112): Type struct C.S is only valid in storage because it contains a (nested) mapping. diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_struct_recusrive_data_location_memory.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_struct_recusrive_data_location_memory.sol index fa09bdeaee..49cf314873 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_struct_recusrive_data_location_memory.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_struct_recusrive_data_location_memory.sol @@ -7,4 +7,3 @@ contract C { } // ---- // TypeError 4103: (148-156): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. -// TypeError 4061: (148-156): Type struct C.U is only valid in storage because it contains a (nested) mapping. From 0cece8e6e745708dfeda209b884301de0d5f9931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 22:34:48 +0200 Subject: [PATCH 0167/1748] CI: Optimize machine sizes for best speed/cost ratio --- .circleci/build_win.ps1 | 4 +- .circleci/config.yml | 155 +++++++++++++++++++++++++++++----------- 2 files changed, 115 insertions(+), 44 deletions(-) diff --git a/.circleci/build_win.ps1 b/.circleci/build_win.ps1 index 9be967c970..730bb63195 100644 --- a/.circleci/build_win.ps1 +++ b/.circleci/build_win.ps1 @@ -20,7 +20,7 @@ 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 .. if ( -not $? ) { throw "CMake configure failed." } -msbuild solidity.sln /p:Configuration=Release /m:5 /v:minimal +msbuild solidity.sln /p:Configuration=Release /m:10 /v:minimal if ( -not $? ) { throw "Build failed." } -..\deps\cmake\bin\cmake --build . -j 5 --target install --config Release +..\deps\cmake\bin\cmake --build . -j 10 --target install --config Release if ( -not $? ) { throw "Install target failed." } diff --git a/.circleci/config.yml b/.circleci/config.yml index cadd37ab23..5a8968deac 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -226,6 +226,14 @@ defaults: - image: << pipeline.parameters.ubuntu-1604-clang-ossfuzz-docker-image >> environment: TERM: xterm + MAKEFLAGS: -j 3 + + - base_ubuntu1604_clang_small: &base_ubuntu1604_clang_small + <<: *base_ubuntu1604_clang + resource_class: small + environment: + TERM: xterm + MAKEFLAGS: -j 2 - base_ubuntu2004_clang: &base_ubuntu2004_clang docker: @@ -236,20 +244,44 @@ defaults: CXX: clang++ MAKEFLAGS: -j 3 - - base_ubuntu2004_clang_xlarge: &base_ubuntu2004_clang_xlarge + - base_ubuntu2004_clang_small: &base_ubuntu2004_clang_small <<: *base_ubuntu2004_clang - resource_class: xlarge + resource_class: small environment: TERM: xterm CC: clang CXX: clang++ - MAKEFLAGS: -j 10 + MAKEFLAGS: -j 2 + + - base_ubuntu2004_clang_large: &base_ubuntu2004_clang_large + <<: *base_ubuntu2004_clang + resource_class: large + environment: + TERM: xterm + CC: clang + CXX: clang++ + MAKEFLAGS: -j 5 - base_ubuntu2004: &base_ubuntu2004 docker: - image: << pipeline.parameters.ubuntu-2004-docker-image >> environment: TERM: xterm + MAKEFLAGS: -j 3 + + - base_ubuntu2004_small: &base_ubuntu2004_small + <<: *base_ubuntu2004 + resource_class: small + environment: + TERM: xterm + MAKEFLAGS: -j 2 + + - base_ubuntu2004_large: &base_ubuntu2004_large + <<: *base_ubuntu2004 + resource_class: large + environment: + TERM: xterm + MAKEFLAGS: -j 5 - base_ubuntu2004_xlarge: &base_ubuntu2004_xlarge <<: *base_ubuntu2004 @@ -258,29 +290,48 @@ defaults: TERM: xterm MAKEFLAGS: -j 10 - - base_buildpack_focal: &base_buildpack_focal + - base_buildpack_focal_small: &base_buildpack_focal_small docker: - image: buildpack-deps:focal + resource_class: small environment: TERM: xterm + MAKEFLAGS: -j 2 - - base_buildpack_latest: &base_buildpack_latest + - base_buildpack_latest_small: &base_buildpack_latest_small docker: - image: buildpack-deps:latest + resource_class: small environment: TERM: xterm + MAKEFLAGS: -j 2 - base_archlinux: &base_archlinux docker: - image: archlinux:base environment: TERM: xterm + MAKEFLAGS: -j 3 + + - base_archlinux_large: &base_archlinux_large + docker: + - image: archlinux:base + resource_class: large + environment: + TERM: xterm + MAKEFLAGS: -j 5 - base_win_powershell: &base_win_powershell executor: name: win/default shell: powershell.exe + - base_win_powershell_large: &base_win_powershell_large + executor: + name: win/default + shell: powershell.exe + size: large + - base_win_cmd: &base_win_cmd executor: name: win/default @@ -291,26 +342,31 @@ defaults: xcode: "11.0.0" environment: TERM: xterm + MAKEFLAGS: -j 5 - - base_ems_xlarge: &base_ems_xlarge + - base_ems_large: &base_ems_large docker: - image: << pipeline.parameters.emscripten-docker-image >> - resource_class: xlarge + resource_class: large environment: TERM: xterm - MAKEFLAGS: -j 10 + MAKEFLAGS: -j 5 - - base_python: &base_python + - base_python_small: &base_python_small docker: - image: circleci/python:3.6 + resource_class: small environment: TERM: xterm + MAKEFLAGS: -j 2 - - base_node_latest: &base_node_latest + - base_node_latest_small: &base_node_latest_small docker: - image: circleci/node + resource_class: small environment: TERM: xterm + MAKEFLAGS: -j 2 # -------------------------------------------------------------------------- # Workflow Templates @@ -394,7 +450,7 @@ defaults: jobs: chk_spelling: - <<: *base_python + <<: *base_python_small steps: - checkout - attach_workspace: @@ -409,7 +465,7 @@ jobs: - gitter_notify_failure_unless_pr chk_docs_examples: - <<: *base_node_latest + <<: *base_node_latest_small steps: - checkout - attach_workspace: @@ -423,7 +479,7 @@ jobs: - gitter_notify_failure_unless_pr chk_coding_style: - <<: *base_buildpack_focal + <<: *base_buildpack_focal_small steps: - checkout - run: @@ -441,7 +497,7 @@ jobs: - gitter_notify_failure_unless_pr chk_errorcodes: - <<: *base_python + <<: *base_python_small steps: - checkout - run: @@ -450,7 +506,7 @@ jobs: - gitter_notify_failure_unless_pr chk_pylint: - <<: *base_buildpack_focal + <<: *base_buildpack_focal_small steps: - checkout - run: @@ -466,7 +522,7 @@ jobs: - gitter_notify_failure_unless_pr chk_antlr_grammar: - <<: *base_buildpack_focal + <<: *base_buildpack_focal_small steps: - checkout - run: @@ -478,7 +534,7 @@ jobs: - gitter_notify_failure_unless_pr chk_buglist: - <<: *base_node_latest + <<: *base_node_latest_small steps: - checkout - run: @@ -493,7 +549,7 @@ jobs: - gitter_notify_failure_unless_pr chk_proofs: - <<: *base_buildpack_latest + <<: *base_buildpack_latest_small steps: - checkout - run: @@ -506,14 +562,14 @@ jobs: - gitter_notify_failure_unless_pr chk_docs_pragma_min_version: - <<: *base_ubuntu2004 + <<: *base_ubuntu2004_small steps: - checkout - run: *run_docs_pragma_min_version - gitter_notify_failure_unless_pr t_ubu_pyscripts: - <<: *base_ubuntu2004 + <<: *base_ubuntu2004_small steps: - checkout - run: @@ -532,6 +588,8 @@ jobs: - gitter_notify_failure_unless_pr 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_ubuntu2004_xlarge steps: - checkout @@ -544,10 +602,11 @@ jobs: # x64 ASAN build, for testing for memory related bugs b_ubu_asan: &b_ubu_asan - <<: *base_ubuntu2004_xlarge + # Runs slightly faster on large and xlarge but we only run it nightly so efficiency matters more. + <<: *base_ubuntu2004 environment: CMAKE_OPTIONS: -DSANITIZE=address - MAKEFLAGS: -j 10 + MAKEFLAGS: -j 3 CMAKE_BUILD_TYPE: Release steps: - checkout @@ -557,7 +616,7 @@ jobs: - gitter_notify_failure_unless_pr b_ubu_clang: &b_ubu_clang - <<: *base_ubuntu2004_clang_xlarge + <<: *base_ubuntu2004_clang_large steps: - checkout - run: *run_build @@ -566,6 +625,7 @@ jobs: - gitter_notify_failure_unless_pr b_ubu_asan_clang: &b_ubu_asan_clang + # This runs a bit faster on large and xlarge but on nightly efficiency matters more. <<: *base_ubuntu2004_clang environment: CC: clang @@ -580,6 +640,7 @@ jobs: - gitter_notify_failure_unless_pr b_ubu_ubsan_clang: &b_ubu_ubsan_clang + # This runs a bit faster on large and xlarge but on nightly efficiency matters more. <<: *base_ubuntu2004_clang environment: CC: clang @@ -600,9 +661,10 @@ jobs: MAKEFLAGS: -j 10 b_ubu_static: - <<: *base_ubuntu2004_xlarge + # Runs 2x faster on large and 3x on xlarge but no other jobs depend on it we can live with medium. + <<: *base_ubuntu2004 environment: - MAKEFLAGS: -j 10 + MAKEFLAGS: -j 3 CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DUSE_CVC4=OFF -DSOLC_STATIC_STDLIBS=ON steps: - checkout @@ -614,11 +676,12 @@ jobs: - gitter_notify_failure_unless_pr b_ubu_codecov: - <<: *base_ubuntu2004_xlarge + # Runs ~30% faster on large but we only run it nightly so efficiency matters more. + <<: *base_ubuntu2004 environment: COVERAGE: ON CMAKE_BUILD_TYPE: Debug - MAKEFLAGS: -j 10 + MAKEFLAGS: -j 3 steps: - checkout - run: *run_build @@ -651,11 +714,11 @@ 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_ubuntu2004_xlarge + <<: *base_ubuntu2004_large environment: CMAKE_BUILD_TYPE: Debug CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 -DUSE_CVC4=OFF - MAKEFLAGS: -j 10 + MAKEFLAGS: -j 5 steps: - checkout - run: *run_build @@ -671,7 +734,7 @@ jobs: - gitter_notify_failure_unless_pr t_ubu_ossfuzz: &t_ubu_ossfuzz - <<: *base_ubuntu1604_clang + <<: *base_ubuntu1604_clang_small steps: - checkout - attach_workspace: @@ -688,10 +751,10 @@ jobs: - gitter_notify_success_unless_pr b_archlinux: - <<: *base_archlinux + <<: *base_archlinux_large environment: TERM: xterm - MAKEFLAGS: -j 3 + MAKEFLAGS: -j 5 steps: - run: name: Install build dependencies @@ -772,7 +835,7 @@ jobs: - gitter_notify_failure_unless_pr b_ems: - <<: *base_ems_xlarge + <<: *base_ems_large steps: - checkout - run: @@ -793,7 +856,7 @@ jobs: - gitter_notify_failure_unless_pr b_docs: - <<: *base_ubuntu2004 + <<: *base_ubuntu2004_small steps: - checkout - run: *setup_prerelease_commit_hash @@ -850,14 +913,15 @@ jobs: <<: *t_ubu_soltest_all t_ubu_cli: &t_ubu_cli - <<: *base_ubuntu2004 + <<: *base_ubuntu2004_small <<: *steps_cmdline_tests t_ubu_release_cli: &t_ubu_release_cli <<: *t_ubu_cli t_ubu_asan_cli: - <<: *base_ubuntu2004 + # Runs slightly faster on medium but we only run it nightly so efficiency matters more. + <<: *base_ubuntu2004_small environment: TERM: xterm ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2 @@ -889,10 +953,11 @@ jobs: <<: *steps_soltest t_ubu_ubsan_clang_cli: - <<: *base_ubuntu2004_clang + <<: *base_ubuntu2004_clang_small <<: *steps_cmdline_tests t_ems_solcjs: + # Unlike other t_ems jobs this one actually runs 2x faster on medium (compared to small). <<: *base_ubuntu2004 steps: - checkout @@ -913,7 +978,7 @@ jobs: - gitter_notify_failure_unless_pr t_ems_ext_hardhat: - <<: *base_node_latest + <<: *base_node_latest_small environment: TERM: xterm HARDHAT_TESTS_SOLC_PATH: /tmp/workspace/soljson.js @@ -948,8 +1013,12 @@ jobs: nodejs_version: type: string default: latest + resource_class: + type: string + default: small docker: - image: circleci/node:<> + resource_class: <> # NOTE: Each external test does 3 separate compile&test runs parallelism: 3 environment: @@ -971,7 +1040,7 @@ jobs: - gitter_notify_failure_unless_pr b_win: &b_win - <<: *base_win_powershell + <<: *base_win_powershell_large steps: # NOTE: Not disabling git's core.autocrlf here because we want to build using the typical Windows config. - checkout @@ -1028,7 +1097,7 @@ jobs: <<: *t_win_soltest b_bytecode_ubu: - <<: *base_ubuntu2004 + <<: *base_ubuntu2004_small steps: - checkout - attach_workspace: @@ -1094,7 +1163,7 @@ jobs: - gitter_notify_failure_unless_pr b_bytecode_ems: - <<: *base_node_latest + <<: *base_node_latest_small environment: SOLC_EMSCRIPTEN: "On" steps: @@ -1111,7 +1180,7 @@ jobs: - gitter_notify_failure_unless_pr t_bytecode_compare: - <<: *base_ubuntu2004 + <<: *base_ubuntu2004_small environment: REPORT_FILES: | bytecode-report-emscripten.txt @@ -1251,6 +1320,7 @@ workflows: project: zeppelin # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' + resource_class: medium - t_ems_ext: <<: *workflow_emscripten name: t_ems_test_ext_ens @@ -1321,3 +1391,4 @@ workflows: <<: *workflow_emscripten name: t_ems_test_ext_colony project: colony + resource_class: medium From 075d7b61527fee52cf8be0b9e7b05295be6a8445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Oct 2021 13:19:04 +0200 Subject: [PATCH 0168/1748] CI: Remove separate compile-only runs for external tests that execute quickly --- .circleci/config.yml | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5a8968deac..af3da5886d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1269,6 +1269,7 @@ workflows: - t_ems_solcjs: *workflow_emscripten - t_ems_ext_hardhat: *workflow_emscripten + # Separate compile-only runs of those external tests where a full run takes much longer. - t_ems_ext: <<: *workflow_emscripten name: t_ems_compile_ext_colony @@ -1281,24 +1282,6 @@ workflows: project: gnosis compile_only: 1 nodejs_version: '14' - - t_ems_ext: - <<: *workflow_emscripten - name: t_ems_compile_ext_gnosis_v2 - project: gnosis-v2 - compile_only: 1 - nodejs_version: '14' - - t_ems_ext: - <<: *workflow_emscripten - name: t_ems_compile_ext_zeppelin - project: zeppelin - compile_only: 1 - - t_ems_ext: - <<: *workflow_emscripten - name: t_ems_compile_ext_ens - project: ens - compile_only: 1 - # NOTE: One of the dependencies (fsevents) fails to build its native extension on node.js 12+. - nodejs_version: '10' # FIXME: Gnosis tests are pretty flaky right now. They often fail on CircleCI due to random ProviderError # and there are also other less frequent problems. See https://github.com/gnosis/safe-contracts/issues/216. From b96d238c2389b3557f9cb0d3a5c29c550145ff99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 5 Nov 2021 17:26:52 +0100 Subject: [PATCH 0169/1748] CI: Double the number of threads for jobs that did slow down after switching to a smaller resource class --- .circleci/config.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index af3da5886d..312695ebf7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -617,6 +617,11 @@ jobs: b_ubu_clang: &b_ubu_clang <<: *base_ubuntu2004_clang_large + environment: + TERM: xterm + CC: clang + CXX: clang++ + MAKEFLAGS: -j 10 steps: - checkout - run: *run_build @@ -664,7 +669,7 @@ jobs: # Runs 2x faster on large and 3x on xlarge but no other jobs depend on it we can live with medium. <<: *base_ubuntu2004 environment: - MAKEFLAGS: -j 3 + MAKEFLAGS: -j 5 CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DUSE_CVC4=OFF -DSOLC_STATIC_STDLIBS=ON steps: - checkout @@ -718,7 +723,7 @@ jobs: environment: CMAKE_BUILD_TYPE: Debug CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 -DUSE_CVC4=OFF - MAKEFLAGS: -j 5 + MAKEFLAGS: -j 10 steps: - checkout - run: *run_build @@ -836,6 +841,9 @@ jobs: b_ems: <<: *base_ems_large + environment: + TERM: xterm + MAKEFLAGS: -j 10 steps: - checkout - run: @@ -1303,7 +1311,7 @@ workflows: project: zeppelin # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' - resource_class: medium + resource_class: large - t_ems_ext: <<: *workflow_emscripten name: t_ems_test_ext_ens From 25a26d2f8bca41e9f488bc8b2eef558da32fb27a Mon Sep 17 00:00:00 2001 From: minami Date: Sun, 5 Dec 2021 16:57:48 +0900 Subject: [PATCH 0170/1748] Fix cheatsheet --- docs/cheatsheet.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index d36a963603..17537914ac 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -81,7 +81,7 @@ Global Variables - ``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.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent - to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)``` + to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)`` - ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatenates variable number of arguments to one byte array` - ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 `_ and `EIP-1559 `_) From 907405e2e06082389be99eb763e797c142f757a1 Mon Sep 17 00:00:00 2001 From: minami Date: Sun, 5 Dec 2021 16:57:59 +0900 Subject: [PATCH 0171/1748] Fix units-and-global-variables --- docs/units-and-global-variables.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index 8a6173280a..ac11e08067 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -135,7 +135,7 @@ ABI Encoding and Decoding Functions - ``abi.encode(...) returns (bytes memory)``: ABI-encodes the given arguments - ``abi.encodePacked(...) returns (bytes memory)``: Performs :ref:`packed encoding ` of the given arguments. Note that packed encoding can be ambiguous! - ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: ABI-encodes the given arguments starting from the second and prepends the given four-byte selector -- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``` +- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`` .. note:: These encoding functions can be used to craft data for external function calls without actually From 6bafeca8a25ec87f50ee2c2de8a8eb1cd549a7e9 Mon Sep 17 00:00:00 2001 From: minami Date: Sun, 5 Dec 2021 16:58:03 +0900 Subject: [PATCH 0172/1748] Fix yul --- docs/yul.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/yul.rst b/docs/yul.rst index ef44a575ba..219905cd5f 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -166,7 +166,7 @@ Inside a code block, the following elements can be used - if statements, e.g. ``if lt(a, b) { sstore(0, 1) }`` - switch statements, e.g. ``switch mload(0) case 0 { revert() } default { mstore(0, 1) }`` - for loops, e.g. ``for { let i := 0} lt(i, 10) { i := add(i, 1) } { mstore(i, 7) }`` -- function definitions, e.g. ``function f(a, b) -> c { c := add(a, b) }``` +- function definitions, e.g. ``function f(a, b) -> c { c := add(a, b) }`` Multiple syntactical elements can follow each other simply separated by whitespace, i.e. there is no terminating ``;`` or newline required. From f0a9cd7504efa34496ab3e0897a1c0cc3b76ebd2 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 6 Dec 2021 16:15:32 +0100 Subject: [PATCH 0173/1748] Typo in changelog. --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index e24cb24628..f5be36a1bf 100644 --- a/Changelog.md +++ b/Changelog.md @@ -104,7 +104,7 @@ Bugfixes: * SMTChecker: Fix false positive in external calls from constructors. * SMTChecker: Fix internal error on some multi-source uses of ``abi.*``, cryptographic functions and constants. * Standard JSON: Fix non-fatal errors in Yul mode being discarded if followed by a fatal error. - * Type Checker: Correct wrong error message in inline assembly complaining about ``.slot`` or ``.offset` not valid when actually ``.length`` was used. + * Type Checker: Correct wrong error message in inline assembly complaining about ``.slot`` or ``.offset`` not valid when actually ``.length`` was used. * Type Checker: Disallow modifier declarations and definitions in interfaces. * Yul Optimizer: Fix a crash in LoadResolver, when ``keccak256`` has particular non-identifier arguments. From d41415325803e97479d111bd70465d7867e0a19c Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 6 Dec 2021 15:59:08 +0100 Subject: [PATCH 0174/1748] Some clarifications on literals. --- docs/types/value-types.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 4cb0dec4fa..49e35d9eae 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -437,14 +437,16 @@ an error. You can prepend (for integer types) or append (for bytesNN types) zero Rational and Integer Literals ----------------------------- -Integer literals are formed from a sequence of numbers in the range 0-9. +Integer literals are formed from a sequence of digits in the range 0-9. They are interpreted as decimals. For example, ``69`` means sixty nine. Octal literals do not exist in Solidity and leading zeros are invalid. -Decimal fraction literals are formed by a ``.`` with at least one number on +Decimal fractional literals are formed by a ``.`` with at least one number on one side. Examples include ``1.``, ``.1`` and ``1.3``. -Scientific notation is also supported, where the base can have fractions and the exponent cannot. +Scientific notation in the form of ``2e10`` is also supported, where the +mantissa can be fractional but the exponent has to be an integer. +The literal ``MeE`` is equivalent to ``M * 10**E``. Examples include ``2e10``, ``-2e10``, ``2e-10``, ``2.5e1``. Underscores can be used to separate the digits of a numeric literal to aid readability. From af02678dee8da8e63c90e2b822f04889843c00d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 8 Dec 2021 20:04:35 +0100 Subject: [PATCH 0175/1748] CI: Adjust job parallelism to actually match available resources - Some jobs don't actually run in parallel but have the `parallelism` setting enabled. - `soltest_all` could be parallelized much more. --- .circleci/config.yml | 4 +--- .circleci/soltest_all.sh | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 312695ebf7..3c47b55c6a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -695,7 +695,6 @@ jobs: t_ubu_codecov: <<: *base_ubuntu2004 - parallelism: 6 environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 1 @@ -878,7 +877,7 @@ jobs: t_ubu_soltest_all: &t_ubu_soltest_all <<: *base_ubuntu2004 - parallelism: 6 + parallelism: 15 # 7 EVM versions, each with/without optimization + 1 ABIv1/@nooptions run <<: *steps_soltest_all t_archlinux_soltest: &t_archlinux_soltest @@ -937,7 +936,6 @@ jobs: t_ubu_asan_soltest: <<: *base_ubuntu2004 - parallelism: 6 environment: EVM: << pipeline.parameters.evm-version >> OPTIMIZE: 0 diff --git a/.circleci/soltest_all.sh b/.circleci/soltest_all.sh index 0c414593f3..5bd5ed9f1c 100755 --- a/.circleci/soltest_all.sh +++ b/.circleci/soltest_all.sh @@ -31,6 +31,7 @@ REPODIR="$(realpath "$(dirname "$0")"/..)" # shellcheck source=scripts/common.sh source "${REPODIR}/scripts/common.sh" +# NOTE: If you add/remove values, remember to update `parallelism` setting in CircleCI config. EVM_VALUES=(homestead byzantium constantinople petersburg istanbul berlin london) DEFAULT_EVM=london [[ " ${EVM_VALUES[*]} " =~ $DEFAULT_EVM ]] From 8ada7db7e9a0e1f0dd0647af3a5943ad294cc153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 10 Dec 2021 15:34:07 +0100 Subject: [PATCH 0176/1748] externalTests: Fix optimizer level 2 to make it actually run without Yul optimizer --- test/externalTests/colony.sh | 1 + test/externalTests/common.sh | 2 +- test/externalTests/gnosis-v2.sh | 1 + test/externalTests/gnosis.sh | 3 ++- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 3aaff44138..4f0ca07574 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -35,6 +35,7 @@ function colony_test local repo="https://github.com/solidity-external-tests/colonyNetwork.git" local branch=develop_080 local config_file="truffle.js" + # On levels 1 and 2 it compiles but tests run out of gas local min_optimizer_level=3 local max_optimizer_level=3 diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 7e651d8c0b..777df7d465 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -245,7 +245,7 @@ function optimizer_settings_for_level case "$level" in 1) echo "{enabled: false}" ;; - 2) echo "{enabled: true}" ;; + 2) echo "{enabled: true, details: {yul: false}}" ;; 3) echo "{enabled: true, details: {yul: true}}" ;; *) printError "Optimizer level not found. Please define OPTIMIZER_LEVEL=[1, 2, 3]" diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 439a3dd91f..803e06b3a2 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -36,6 +36,7 @@ function gnosis_safe_test local repo="https://github.com/solidity-external-tests/safe-contracts.git" local branch=v2_080 local config_file="truffle-config.js" + # level 1: "Error: while migrating GnosisSafe: Returned error: base fee exceeds gas limit" local min_optimizer_level=2 local max_optimizer_level=3 diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 32b76d9c90..a419ea6e75 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -35,7 +35,8 @@ function gnosis_safe_test local repo="https://github.com/solidity-external-tests/safe-contracts.git" local branch=development_080 local config_file="truffle-config.js" - local min_optimizer_level=2 + # levels 1 and 2: "Stack too deep" error + local min_optimizer_level=3 local max_optimizer_level=3 local selected_optimizer_levels From 937597c1cd4b199389a52c1775b44f3667f26f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 9 Dec 2021 14:51:45 +0100 Subject: [PATCH 0177/1748] Use unique name for gnosis-v2 ext test --- test/externalTests/gnosis-v2.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 803e06b3a2..f43e415674 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -63,4 +63,4 @@ function gnosis_safe_test done } -external_test Gnosis-Safe gnosis_safe_test +external_test Gnosis-Safe-V2 gnosis_safe_test From 5fb0246f1c057fcdb4e3e7e0cff8cda7489695d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 3 Dec 2021 15:26:45 +0100 Subject: [PATCH 0178/1748] Use the right config file name in ENS external test --- 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 9fed91be1f..c2deca5d2f 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -34,7 +34,7 @@ function ens_test { local repo="https://github.com/ensdomains/ens.git" local branch=master - local config_file="truffle-config.js" + local config_file="truffle.js" local min_optimizer_level=1 local max_optimizer_level=3 From 0edbd90f526d9792c381b10974dc9039e4b6724f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 3 Dec 2021 12:53:50 +0100 Subject: [PATCH 0179/1748] externalTests: Use fail() function to simplify error checks --- test/externalTests/common.sh | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 7e651d8c0b..4020fc7a1d 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -35,18 +35,12 @@ function print_optimizer_levels_or_exit function verify_input { - if [ ! -f "$1" ]; then - printError "Usage: $0 " - exit 1 - fi + [[ -f "$1" ]] || fail "Usage: $0 " } function verify_version_input { - if [ -z "$1" ] || [ ! -f "$1" ] || [ -z "$2" ]; then - printError "Usage: $0 " - exit 1 - fi + [[ $1 != "" && -f "$1" && $2 != "" ]] || fail "Usage: $0 " } function setup @@ -248,8 +242,7 @@ function optimizer_settings_for_level 2) echo "{enabled: true}" ;; 3) echo "{enabled: true, details: {yul: true}}" ;; *) - printError "Optimizer level not found. Please define OPTIMIZER_LEVEL=[1, 2, 3]" - exit 1 + fail "Optimizer level not found. Please define OPTIMIZER_LEVEL=[1, 2, 3]" ;; esac } @@ -356,10 +349,7 @@ function external_test echo "===========================" DIR=$(mktemp -d -t "ext-test-${name}-XXXXXX") ( - if [ -z "$main_fn" ]; then - printError "Test main function not defined." - exit 1 - fi + [[ "$main_fn" != "" ]] || fail "Test main function not defined." $main_fn ) rm -rf "$DIR" From 081b80ccb2170528e501ab451296407d5f434078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 3 Dec 2021 12:57:39 +0100 Subject: [PATCH 0180/1748] externalTests: Refactor setup and input verification --- test/externalTests.sh | 19 +++++------ test/externalTests/colony.sh | 6 ++-- test/externalTests/common.sh | 45 ++++++++++----------------- test/externalTests/ens.sh | 6 ++-- test/externalTests/gnosis-v2.sh | 7 ++--- test/externalTests/gnosis.sh | 6 ++-- test/externalTests/solc-js/solc-js.sh | 6 ++-- test/externalTests/zeppelin.sh | 8 ++--- 8 files changed, 44 insertions(+), 59 deletions(-) diff --git a/test/externalTests.sh b/test/externalTests.sh index 28af6f835a..c9b30d0fe4 100755 --- a/test/externalTests.sh +++ b/test/externalTests.sh @@ -28,25 +28,20 @@ set -e -if [ ! -f "$1" ] -then - echo "Usage: $0 " - exit 1 -fi - -SOLJSON="$1" REPO_ROOT="$(dirname "$0")" source scripts/common.sh source test/externalTests/common.sh +verify_input "$@" + printTask "Running external tests..." -"$REPO_ROOT/externalTests/zeppelin.sh" "$SOLJSON" -"$REPO_ROOT/externalTests/gnosis.sh" "$SOLJSON" -"$REPO_ROOT/externalTests/gnosis-v2.sh" "$SOLJSON" -"$REPO_ROOT/externalTests/colony.sh" "$SOLJSON" -"$REPO_ROOT/externalTests/ens.sh" "$SOLJSON" +"$REPO_ROOT/externalTests/zeppelin.sh" "$@" +"$REPO_ROOT/externalTests/gnosis.sh" "$@" +"$REPO_ROOT/externalTests/gnosis-v2.sh" "$@" +"$REPO_ROOT/externalTests/colony.sh" "$@" +"$REPO_ROOT/externalTests/ens.sh" "$@" # Disabled temporarily as it needs to be updated to latest Truffle first. #test_truffle Gnosis https://github.com/axic/pm-contracts.git solidity-050 diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 3aaff44138..16c8594068 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -24,8 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh -verify_input "$1" -SOLJSON="$1" +verify_input "$@" +BINARY_PATH="$1" function compile_fn { yarn run provision:token:contracts; } function test_fn { yarn run test:contracts; } @@ -42,7 +42,7 @@ function colony_test selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") print_optimizer_levels_or_exit "$selected_optimizer_levels" - setup_solcjs "$DIR" "$SOLJSON" + setup_solcjs "$DIR" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" neutralize_package_json_hooks diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 4020fc7a1d..5ee22873a9 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -35,52 +35,41 @@ function print_optimizer_levels_or_exit function verify_input { - [[ -f "$1" ]] || fail "Usage: $0 " -} + local binary_path="$1" -function verify_version_input -{ - [[ $1 != "" && -f "$1" && $2 != "" ]] || fail "Usage: $0 " + (( $# == 1 )) || fail "Usage: $0 " + [[ -f "$binary_path" ]] || fail "The compiler binary does not exist at '${binary_path}'" } -function setup -{ - local soljson="$1" - local branch="$2" - - setup_solcjs "$DIR" "$soljson" "$branch" "solc" - cd solc -} function setup_solcjs { - local dir="$1" - local soljson="$2" - local branch="${3:-master}" - local path="${4:-solc/}" + local test_dir="$1" + local binary_path="$2" + local solcjs_branch="${3:-master}" + local install_dir="${4:-solc/}" - cd "$dir" + cd "$test_dir" printLog "Setting up solc-js..." - git clone --depth 1 -b "$branch" https://github.com/ethereum/solc-js.git "$path" - - cd "$path" + git clone --depth 1 -b "$solcjs_branch" https://github.com/ethereum/solc-js.git "$install_dir" + pushd "$install_dir" npm install - cp "$soljson" soljson.js + cp "$binary_path" soljson.js SOLCVERSION=$(./solcjs --version) SOLCVERSION_SHORT=$(echo "$SOLCVERSION" | sed -En 's/^([0-9.]+).*\+commit\.[0-9a-f]+.*$/\1/p') - printLog "Using solcjs version $SOLCVERSION" - cd .. + printLog "Using compiler version $SOLCVERSION" + popd } function download_project { local repo="$1" - local branch="$2" - local dir="$3" + local solcjs_branch="$2" + local test_dir="$3" - printLog "Cloning $branch of $repo..." - git clone --depth 1 "$repo" -b "$branch" "$dir/ext" + printLog "Cloning $solcjs_branch of $repo..." + git clone --depth 1 "$repo" -b "$solcjs_branch" "$test_dir/ext" cd ext echo "Current commit hash: $(git rev-parse HEAD)" } diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index 9fed91be1f..45ff338fd0 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -24,8 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh -verify_input "$1" -export SOLJSON="$1" +verify_input "$@" +BINARY_PATH="$1" function compile_fn { npx truffle compile; } function test_fn { npm run test; } @@ -42,7 +42,7 @@ function ens_test selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") print_optimizer_levels_or_exit "$selected_optimizer_levels" - setup_solcjs "$DIR" "$SOLJSON" + setup_solcjs "$DIR" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" # Use latest Truffle. Older versions crash on the output from 0.8.0. diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 439a3dd91f..878a1f2778 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -24,10 +24,9 @@ set -e source scripts/common.sh source test/externalTests/common.sh -verify_input "$1" -SOLJSON="$1" +verify_input "$@" +BINARY_PATH="$1" -function install_fn { npm install --package-lock; } function compile_fn { npx truffle compile; } function test_fn { npm test; } @@ -43,7 +42,7 @@ function gnosis_safe_test selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") print_optimizer_levels_or_exit "$selected_optimizer_levels" - setup_solcjs "$DIR" "$SOLJSON" + setup_solcjs "$DIR" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 32b76d9c90..c721ae8807 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -24,8 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh -verify_input "$1" -SOLJSON="$1" +verify_input "$@" +BINARY_PATH="$1" function compile_fn { npx truffle compile; } function test_fn { npm test; } @@ -42,7 +42,7 @@ function gnosis_safe_test selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") print_optimizer_levels_or_exit "$selected_optimizer_levels" - setup_solcjs "$DIR" "$SOLJSON" + setup_solcjs "$DIR" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json diff --git a/test/externalTests/solc-js/solc-js.sh b/test/externalTests/solc-js/solc-js.sh index a3b24db9ec..4ca6e3d008 100755 --- a/test/externalTests/solc-js/solc-js.sh +++ b/test/externalTests/solc-js/solc-js.sh @@ -24,10 +24,11 @@ set -e source scripts/common.sh source test/externalTests/common.sh -verify_version_input "$1" "$2" SOLJSON="$1" VERSION="$2" +[[ $SOLJSON != "" && -f "$SOLJSON" && $VERSION != "" ]] || fail "Usage: $0 " + function compile_fn { echo "Nothing to compile."; } function test_fn { npm test; } @@ -37,7 +38,8 @@ function solcjs_test SOLCJS_INPUT_DIR="$TEST_DIR"/test/externalTests/solc-js # set up solc-js on the branch specified - setup "$SOLJSON" master + setup_solcjs "$DIR" "$SOLJSON" master solc/ + cd solc/ printLog "Updating index.js file..." echo "require('./determinism.js');" >> test/index.js diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index cd290b860f..86530bcc3c 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -24,8 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh -verify_input "$1" -SOLJSON="$1" +verify_input "$@" +BINARY_PATH="$1" function compile_fn { npm run compile; } function test_fn { npm test; } @@ -42,11 +42,11 @@ function zeppelin_test selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") print_optimizer_levels_or_exit "$selected_optimizer_levels" - setup_solcjs "$DIR" "$SOLJSON" + setup_solcjs "$DIR" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" neutralize_package_json_hooks - force_hardhat_compiler_binary "$config_file" "$SOLJSON" + force_hardhat_compiler_binary "$config_file" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$min_optimizer_level" npm install From 68ff073b3b165132790819720c4f626c53d0c159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 3 Dec 2021 13:44:03 +0100 Subject: [PATCH 0181/1748] externalTests.sh: Remove outdated commented-out command to run gnosis - A newer command is already enabled above it --- test/externalTests.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/externalTests.sh b/test/externalTests.sh index c9b30d0fe4..86f13401e9 100755 --- a/test/externalTests.sh +++ b/test/externalTests.sh @@ -42,6 +42,3 @@ printTask "Running external tests..." "$REPO_ROOT/externalTests/gnosis-v2.sh" "$@" "$REPO_ROOT/externalTests/colony.sh" "$@" "$REPO_ROOT/externalTests/ens.sh" "$@" - -# Disabled temporarily as it needs to be updated to latest Truffle first. -#test_truffle Gnosis https://github.com/axic/pm-contracts.git solidity-050 From eb8e304b47c8a9da2004e92d6ba2185bdee31825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 3 Dec 2021 14:51:05 +0100 Subject: [PATCH 0182/1748] externalTests: Add support for using a native binary --- .circleci/config.yml | 2 +- test/externalTests/colony.sh | 12 ++-- test/externalTests/common.sh | 89 +++++++++++++++++++-------- test/externalTests/ens.sh | 12 ++-- test/externalTests/gnosis-v2.sh | 12 ++-- test/externalTests/gnosis.sh | 12 ++-- test/externalTests/solc-js/solc-js.sh | 2 +- test/externalTests/zeppelin.sh | 7 ++- 8 files changed, 97 insertions(+), 51 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 312695ebf7..1013432223 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1044,7 +1044,7 @@ jobs: - run: name: External <> tests command: | - test/externalTests/<>.sh /tmp/workspace/soljson.js + test/externalTests/<>.sh solcjs /tmp/workspace/soljson.js - gitter_notify_failure_unless_pr b_win: &b_win diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 16c8594068..dff745d683 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -25,7 +25,8 @@ source scripts/common.sh source test/externalTests/common.sh verify_input "$@" -BINARY_PATH="$1" +BINARY_TYPE="$1" +BINARY_PATH="$2" function compile_fn { yarn run provision:token:contracts; } function test_fn { yarn run test:contracts; } @@ -42,11 +43,12 @@ function colony_test selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") print_optimizer_levels_or_exit "$selected_optimizer_levels" - setup_solcjs "$DIR" "$BINARY_PATH" + setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" + [[ $BINARY_TYPE == native ]] && replace_global_solc "$BINARY_PATH" neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$min_optimizer_level" yarn git submodule update --init @@ -56,10 +58,10 @@ function colony_test cd .. replace_version_pragmas - force_solc_modules "${DIR}/solc" + [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" for level in $selected_optimizer_levels; do - truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$level" compile_fn test_fn done } diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 5ee22873a9..b36861d07c 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -35,31 +35,43 @@ function print_optimizer_levels_or_exit function verify_input { - local binary_path="$1" + local binary_type="$1" + local binary_path="$2" - (( $# == 1 )) || fail "Usage: $0 " + (( $# == 2 )) || fail "Usage: $0 native|solcjs " + [[ $binary_type == native || $binary_type == solcjs ]] || fail "Invalid binary type: '${binary_type}'. Must be either 'native' or 'solcjs'." [[ -f "$binary_path" ]] || fail "The compiler binary does not exist at '${binary_path}'" } - -function setup_solcjs +function setup_solc { local test_dir="$1" - local binary_path="$2" - local solcjs_branch="${3:-master}" - local install_dir="${4:-solc/}" + local binary_type="$2" + local binary_path="$3" + local solcjs_branch="${4:-master}" + local install_dir="${5:-solc/}" + + [[ $binary_type == native || $binary_type == solcjs ]] || assertFail cd "$test_dir" - printLog "Setting up solc-js..." - git clone --depth 1 -b "$solcjs_branch" https://github.com/ethereum/solc-js.git "$install_dir" - pushd "$install_dir" - npm install - cp "$binary_path" soljson.js - SOLCVERSION=$(./solcjs --version) + if [[ $binary_type == solcjs ]] + then + printLog "Setting up solc-js..." + git clone --depth 1 -b "$solcjs_branch" https://github.com/ethereum/solc-js.git "$install_dir" + + pushd "$install_dir" + npm install + cp "$binary_path" soljson.js + SOLCVERSION=$(./solcjs --version) + popd + else + printLog "Setting up solc..." + SOLCVERSION=$("$binary_path" --version | tail -n 1 | sed -n -E 's/^Version: (.*)$/\1/p') + fi + SOLCVERSION_SHORT=$(echo "$SOLCVERSION" | sed -En 's/^([0-9.]+).*\+commit\.[0-9a-f]+.*$/\1/p') printLog "Using compiler version $SOLCVERSION" - popd } function download_project @@ -127,13 +139,19 @@ function force_solc_modules function force_truffle_compiler_settings { local config_file="$1" - local solc_path="$2" - local level="$3" - local evm_version="${4:-"$CURRENT_EVM_VERSION"}" + local binary_type="$2" + local solc_path="$3" + local level="$4" + local evm_version="${5:-"$CURRENT_EVM_VERSION"}" + + [[ $binary_type == native || $binary_type == solcjs ]] || assertFail + + [[ $binary_type == native ]] && local solc_path="native" printLog "Forcing Truffle compiler settings..." echo "-------------------------------------" echo "Config file: $config_file" + echo "Binary type: $binary_type" echo "Compiler path: $solc_path" echo "Optimization level: $level" echo "Optimizer settings: $(optimizer_settings_for_level "$level")" @@ -148,13 +166,15 @@ function force_truffle_compiler_settings function force_hardhat_compiler_binary { local config_file="$1" - local solc_path="$2" + local binary_type="$2" + local solc_path="$3" printLog "Configuring Hardhat..." echo "-------------------------------------" echo "Config file: ${config_file}" + echo "Binary type: ${binary_type}" echo "Compiler path: ${solc_path}" - hardhat_solc_build_subtask "$SOLCVERSION_SHORT" "$SOLCVERSION" "$solc_path" >> "$config_file" + hardhat_solc_build_subtask "$SOLCVERSION_SHORT" "$SOLCVERSION" "$binary_type" "$solc_path" >> "$config_file" } function force_hardhat_compiler_settings @@ -236,6 +256,16 @@ function optimizer_settings_for_level esac } +function replace_global_solc +{ + local solc_path="$1" + + [[ ! -e solc ]] || fail "A file named 'solc' already exists in '${PWD}'." + + ln -s "$solc_path" solc + export PATH="$PWD:$PATH" +} + function truffle_compiler_settings { local solc_path="$1" @@ -256,7 +286,13 @@ function truffle_compiler_settings function hardhat_solc_build_subtask { local solc_version="$1" local full_solc_version="$2" - local solc_path="$3" + local binary_type="$3" + local solc_path="$4" + + [[ $binary_type == native || $binary_type == solcjs ]] || assertFail + + [[ $binary_type == native ]] && local is_solcjs=false + [[ $binary_type == solcjs ]] && local is_solcjs=true echo "const {TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD} = require('hardhat/builtin-tasks/task-names');" echo "const assert = require('assert');" @@ -265,7 +301,7 @@ function hardhat_solc_build_subtask { echo " assert(args.solcVersion == '${solc_version}', 'Unexpected solc version: ' + args.solcVersion)" echo " return {" echo " compilerPath: '$(realpath "$solc_path")'," - echo " isSolcJs: true," + echo " isSolcJs: ${is_solcjs}," echo " version: args.solcVersion," echo " longVersion: '${full_solc_version}'" echo " }" @@ -307,13 +343,14 @@ function compile_and_run_test function truffle_run_test { local config_file="$1" - local solc_path="$2" - local optimizer_level="$3" - local compile_fn="$4" - local test_fn="$5" + local binary_type="$2" + local solc_path="$3" + local optimizer_level="$4" + local compile_fn="$5" + local test_fn="$6" truffle_clean - force_truffle_compiler_settings "$config_file" "$solc_path" "$optimizer_level" + force_truffle_compiler_settings "$config_file" "$binary_type" "$solc_path" "$optimizer_level" compile_and_run_test compile_fn test_fn truffle_verify_compiler_version } diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index 45ff338fd0..5c7d582704 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -25,7 +25,8 @@ source scripts/common.sh source test/externalTests/common.sh verify_input "$@" -BINARY_PATH="$1" +BINARY_TYPE="$1" +BINARY_PATH="$2" function compile_fn { npx truffle compile; } function test_fn { npm run test; } @@ -42,22 +43,23 @@ function ens_test selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") print_optimizer_levels_or_exit "$selected_optimizer_levels" - setup_solcjs "$DIR" "$BINARY_PATH" + setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" + [[ $BINARY_TYPE == native ]] && replace_global_solc "$BINARY_PATH" # Use latest Truffle. Older versions crash on the output from 0.8.0. force_truffle_version ^5.1.55 neutralize_package_lock neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$min_optimizer_level" npm install replace_version_pragmas - force_solc_modules "${DIR}/solc" + [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" for level in $selected_optimizer_levels; do - truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$level" compile_fn test_fn done } diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 878a1f2778..b2f6c4a830 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -25,7 +25,8 @@ source scripts/common.sh source test/externalTests/common.sh verify_input "$@" -BINARY_PATH="$1" +BINARY_TYPE="$1" +BINARY_PATH="$2" function compile_fn { npx truffle compile; } function test_fn { npm test; } @@ -42,22 +43,23 @@ function gnosis_safe_test selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") print_optimizer_levels_or_exit "$selected_optimizer_levels" - setup_solcjs "$DIR" "$BINARY_PATH" + setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" + [[ $BINARY_TYPE == native ]] && replace_global_solc "$BINARY_PATH" sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json sed -i -E 's|"@gnosis.pm/util-contracts": "[^"]+"|"@gnosis.pm/util-contracts": "github:solidity-external-tests/util-contracts#solc-7_080"|g' package.json neutralize_package_lock neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$min_optimizer_level" npm install --package-lock replace_version_pragmas - force_solc_modules "${DIR}/solc" + [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" for level in $selected_optimizer_levels; do - truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$level" compile_fn test_fn done } diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index c721ae8807..69d068474e 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -25,7 +25,8 @@ source scripts/common.sh source test/externalTests/common.sh verify_input "$@" -BINARY_PATH="$1" +BINARY_TYPE="$1" +BINARY_PATH="$2" function compile_fn { npx truffle compile; } function test_fn { npm test; } @@ -42,21 +43,22 @@ function gnosis_safe_test selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") print_optimizer_levels_or_exit "$selected_optimizer_levels" - setup_solcjs "$DIR" "$BINARY_PATH" + setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" + [[ $BINARY_TYPE == native ]] && replace_global_solc "$BINARY_PATH" sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json neutralize_package_lock neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "${DIR}/solc" "$min_optimizer_level" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$min_optimizer_level" npm install --package-lock replace_version_pragmas - force_solc_modules "${DIR}/solc" + [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" for level in $selected_optimizer_levels; do - truffle_run_test "$config_file" "${DIR}/solc" "$level" compile_fn test_fn + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$level" compile_fn test_fn done } diff --git a/test/externalTests/solc-js/solc-js.sh b/test/externalTests/solc-js/solc-js.sh index 4ca6e3d008..33b43e6430 100755 --- a/test/externalTests/solc-js/solc-js.sh +++ b/test/externalTests/solc-js/solc-js.sh @@ -38,7 +38,7 @@ function solcjs_test SOLCJS_INPUT_DIR="$TEST_DIR"/test/externalTests/solc-js # set up solc-js on the branch specified - setup_solcjs "$DIR" "$SOLJSON" master solc/ + setup_solc "$DIR" solcjs "$SOLJSON" master solc/ cd solc/ printLog "Updating index.js file..." diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 86530bcc3c..0759a3aec6 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -25,7 +25,8 @@ source scripts/common.sh source test/externalTests/common.sh verify_input "$@" -BINARY_PATH="$1" +BINARY_TYPE="$1" +BINARY_PATH="$2" function compile_fn { npm run compile; } function test_fn { npm test; } @@ -42,11 +43,11 @@ function zeppelin_test selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") print_optimizer_levels_or_exit "$selected_optimizer_levels" - setup_solcjs "$DIR" "$BINARY_PATH" + setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" neutralize_package_json_hooks - force_hardhat_compiler_binary "$config_file" "$BINARY_PATH" + force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" force_hardhat_compiler_settings "$config_file" "$min_optimizer_level" npm install From f5830c451625bad5e667293ec41564ce287b6889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 7 Dec 2021 16:30:25 +0100 Subject: [PATCH 0183/1748] CI: Extend t_ems job to allow using both emscripten and native binaries --- .circleci/config.yml | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1013432223..6c60be470e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1015,6 +1015,11 @@ jobs: parameters: project: type: string + binary_type: + type: enum + enum: + - solcjs + - native compile_only: type: integer default: 0 @@ -1037,14 +1042,26 @@ jobs: - attach_workspace: at: /tmp/workspace - run: - name: Install dependencies + name: Install lsof command: | # lsof is used by Colony in its stop-blockchain-client.sh script - sudo apt-get -qy install lsof - - run: - name: External <> tests - command: | - test/externalTests/<>.sh solcjs /tmp/workspace/soljson.js + sudo apt-get --quiet --assume-yes --no-install-recommends install lsof + - when: + condition: + equal: [<< parameters.binary_type >>, "solcjs"] + steps: + - run: + name: External <> tests (solcjs) + command: | + test/externalTests/<>.sh solcjs /tmp/workspace/soljson.js + - when: + condition: + equal: [<< parameters.binary_type >>, "native"] + steps: + - run: + name: External <> tests (native) + command: | + test/externalTests/<>.sh native /tmp/workspace/solc/solc - gitter_notify_failure_unless_pr b_win: &b_win @@ -1282,12 +1299,14 @@ workflows: <<: *workflow_emscripten name: t_ems_compile_ext_colony project: colony + binary_type: solcjs compile_only: 1 nodejs_version: '14' - t_ems_ext: <<: *workflow_emscripten name: t_ems_compile_ext_gnosis project: gnosis + binary_type: solcjs compile_only: 1 nodejs_version: '14' @@ -1297,18 +1316,21 @@ workflows: # <<: *workflow_emscripten # name: t_ems_test_ext_gnosis # project: gnosis + # binary_type: solcjs # # NOTE: Tests do not start on node.js 14 ("ganache-cli exited early with code 1"). # nodejs_version: '12' - t_ems_ext: <<: *workflow_emscripten name: t_ems_test_ext_gnosis_v2 project: gnosis-v2 + binary_type: solcjs # NOTE: Tests do not start on node.js 14 ("ganache-cli exited early with code 1"). nodejs_version: '12' - t_ems_ext: <<: *workflow_emscripten name: t_ems_test_ext_zeppelin project: zeppelin + binary_type: solcjs # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' resource_class: large @@ -1316,6 +1338,7 @@ workflows: <<: *workflow_emscripten name: t_ems_test_ext_ens project: ens + binary_type: solcjs # NOTE: One of the dependencies (fsevents) fails to build its native extension on node.js 12+. nodejs_version: '10' @@ -1382,4 +1405,5 @@ workflows: <<: *workflow_emscripten name: t_ems_test_ext_colony project: colony + binary_type: solcjs resource_class: medium From 3649103e4209351e18d9ca99763349d888224640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 7 Dec 2021 16:34:07 +0100 Subject: [PATCH 0184/1748] Switch most external tests to use native compiler built by b_ubu_static --- .circleci/config.yml | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6c60be470e..4798c11669 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -396,6 +396,11 @@ defaults: requires: - b_ubu_release + - workflow_ubuntu2004_static: &workflow_ubuntu2004_static + <<: *workflow_trigger_on_tags + requires: + - b_ubu_static + - workflow_archlinux: &workflow_archlinux <<: *workflow_trigger_on_tags requires: @@ -666,10 +671,11 @@ jobs: MAKEFLAGS: -j 10 b_ubu_static: - # Runs 2x faster on large and 3x on xlarge but no other jobs depend on it we can live with medium. - <<: *base_ubuntu2004 + # On large runs 2x faster than on medium. 3x on xlarge. + <<: *base_ubuntu2004_xlarge environment: - MAKEFLAGS: -j 5 + TERM: xterm + MAKEFLAGS: -j 10 CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DUSE_CVC4=OFF -DSOLC_STATIC_STDLIBS=ON steps: - checkout @@ -678,6 +684,7 @@ jobs: name: strip binary command: strip build/solc/solc - store_artifacts: *artifacts_solc + - persist_to_workspace: *artifacts_executables - gitter_notify_failure_unless_pr b_ubu_codecov: @@ -1303,10 +1310,10 @@ workflows: compile_only: 1 nodejs_version: '14' - t_ems_ext: - <<: *workflow_emscripten - name: t_ems_compile_ext_gnosis + <<: *workflow_ubuntu2004_static + name: t_native_compile_ext_gnosis project: gnosis - binary_type: solcjs + binary_type: native compile_only: 1 nodejs_version: '14' @@ -1314,31 +1321,31 @@ workflows: # and there are also other less frequent problems. See https://github.com/gnosis/safe-contracts/issues/216. #- t_ems_ext: # <<: *workflow_emscripten - # name: t_ems_test_ext_gnosis + # name: t_native_test_ext_gnosis # project: gnosis - # binary_type: solcjs + # binary_type: native # # NOTE: Tests do not start on node.js 14 ("ganache-cli exited early with code 1"). # nodejs_version: '12' - t_ems_ext: - <<: *workflow_emscripten - name: t_ems_test_ext_gnosis_v2 + <<: *workflow_ubuntu2004_static + name: t_native_test_ext_gnosis_v2 project: gnosis-v2 - binary_type: solcjs + binary_type: native # NOTE: Tests do not start on node.js 14 ("ganache-cli exited early with code 1"). nodejs_version: '12' - t_ems_ext: - <<: *workflow_emscripten - name: t_ems_test_ext_zeppelin + <<: *workflow_ubuntu2004_static + name: t_native_test_ext_zeppelin project: zeppelin - binary_type: solcjs + binary_type: native # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' resource_class: large - t_ems_ext: - <<: *workflow_emscripten - name: t_ems_test_ext_ens + <<: *workflow_ubuntu2004_static + name: t_native_test_ext_ens project: ens - binary_type: solcjs + binary_type: native # NOTE: One of the dependencies (fsevents) fails to build its native extension on node.js 12+. nodejs_version: '10' From 01d45a195226f0d6c0dd252582dd154857b621e8 Mon Sep 17 00:00:00 2001 From: Omkar Nikhal <69253915+gitpushOmnik@users.noreply.github.com> Date: Thu, 9 Dec 2021 23:42:07 +0530 Subject: [PATCH 0185/1748] Remove redundant typo --- docs/brand-guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/brand-guide.rst b/docs/brand-guide.rst index fc03f35d93..5601b16a8e 100644 --- a/docs/brand-guide.rst +++ b/docs/brand-guide.rst @@ -59,7 +59,7 @@ Under the following terms: - **Attribution** — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any - reasonable manner, but not in any way that suggests the the Solidity + reasonable manner, but not in any way that suggests that the Solidity core team endorses you or your use. When using the Solidity logo, please respect the Solidity logo guidelines. From 6afb63200c704ec019ec0f7c3e8d5b1db30cbba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 9 Dec 2021 16:36:09 +0100 Subject: [PATCH 0186/1748] externalTests: Use `yarn install` instead of `yarn` in colony ext test to avoid compiling contracts twice --- test/externalTests/colony.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index dff745d683..65e4e42561 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -49,7 +49,7 @@ function colony_test neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$min_optimizer_level" - yarn + yarn install git submodule update --init cd lib From f0aadcf577bd543ba20e3688ca088b233f28f557 Mon Sep 17 00:00:00 2001 From: dinah Date: Thu, 9 Dec 2021 20:18:28 -0600 Subject: [PATCH 0187/1748] Remove stale link. --- 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 c448d7671d..aab0faf7c5 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -313,7 +313,7 @@ likely it will be. since it is not up to the submitter of a transaction, but up to the miners to determine in which block the transaction is included. If you want to schedule future calls of your contract, you can use - the `alarm clock `_ or a similar oracle service. + a smart contract automation tool or an oracle service. .. _the-ethereum-virtual-machine: From e6179d5356d532bad82b15c2ffa80b8e65fae2cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 10 Dec 2021 14:59:13 +0100 Subject: [PATCH 0188/1748] CI: Run `t_ems_test_ext_colony` on nodejs 14 - Otherwise it seems to require python, which is not available in CI. We could install it but we'll probably run into other issues on latest node and the switch to latest was not intentional anyway. --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4798c11669..512b46a78b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1413,4 +1413,5 @@ workflows: name: t_ems_test_ext_colony project: colony binary_type: solcjs + nodejs_version: '14' resource_class: medium From 0e6388a90769783fc0cd1d4455fc5c58fec172f0 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 13 Dec 2021 14:52:17 +0100 Subject: [PATCH 0189/1748] Clarify FileReader interface. --- libsolidity/interface/FileReader.cpp | 4 ++-- libsolidity/interface/FileReader.h | 15 +++++++------- solc/CommandLineInterface.cpp | 30 ++++++++++++++-------------- test/solc/CommandLineInterface.cpp | 28 +++++++++++++------------- 4 files changed, 38 insertions(+), 39 deletions(-) diff --git a/libsolidity/interface/FileReader.cpp b/libsolidity/interface/FileReader.cpp index cfd1feb338..65cf70e5a4 100644 --- a/libsolidity/interface/FileReader.cpp +++ b/libsolidity/interface/FileReader.cpp @@ -84,7 +84,7 @@ void FileReader::allowDirectory(boost::filesystem::path _path) m_allowedDirectories.insert(std::move(_path)); } -void FileReader::setSource(boost::filesystem::path const& _path, SourceCode _source) +void FileReader::addOrUpdateFile(boost::filesystem::path const& _path, SourceCode _source) { m_sourceCodes[cliPathToSourceUnitName(_path)] = std::move(_source); } @@ -94,7 +94,7 @@ void FileReader::setStdin(SourceCode _source) m_sourceCodes[""] = std::move(_source); } -void FileReader::setSources(StringMap _sources) +void FileReader::setSourceUnits(StringMap _sources) { m_sourceCodes = std::move(_sources); } diff --git a/libsolidity/interface/FileReader.h b/libsolidity/interface/FileReader.h index 71f5819df6..71ca5fc5d1 100644 --- a/libsolidity/interface/FileReader.h +++ b/libsolidity/interface/FileReader.h @@ -61,18 +61,17 @@ class FileReader void allowDirectory(boost::filesystem::path _path); FileSystemPathSet const& allowedDirectories() const noexcept { return m_allowedDirectories; } - StringMap const& sourceCodes() const noexcept { return m_sourceCodes; } - - /// Retrieves the source code for a given source unit name. - SourceCode const& sourceCode(SourceUnitName const& _sourceUnitName) const { return m_sourceCodes.at(_sourceUnitName); } + /// @returns all sources by their internal source unit names. + StringMap const& sourceUnits() const noexcept { return m_sourceCodes; } /// Resets all sources to the given map of source unit name to source codes. /// Does not enforce @a allowedDirectories(). - void setSources(StringMap _sources); + void setSourceUnits(StringMap _sources); - /// Adds the source code under a source unit name created by normalizing the file path. + /// Adds the source code under a source unit name created by normalizing the file path + /// or changes an existing source. /// Does not enforce @a allowedDirectories(). - void setSource(boost::filesystem::path const& _path, SourceCode _source); + void addOrUpdateFile(boost::filesystem::path const& _path, SourceCode _source); /// Adds the source code under the source unit name of @a . /// Does not enforce @a allowedDirectories(). @@ -83,7 +82,7 @@ class FileReader /// The read will only succeed if the canonical path of the file is within one of the @a allowedDirectories(). /// @param _kind must be equal to "source". Other values are not supported. /// @return Content of the loaded file or an error message. If the operation succeeds, a copy of - /// the content is retained in @a sourceCodes() under the key of @a _sourceUnitName. If the key + /// the content is retained in @a sourceUnits() under the key of @a _sourceUnitName. If the key /// already exists, previous content is discarded. frontend::ReadCallback::Result readFile(std::string const& _kind, std::string const& _sourceUnitName); diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 4610741020..94bfd8a68b 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -483,7 +483,7 @@ void CommandLineInterface::readInputFiles() } else { - m_fileReader.setSource(infile, move(fileContent)); + m_fileReader.addOrUpdateFile(infile, move(fileContent)); m_fileReader.allowDirectory(boost::filesystem::canonical(infile).remove_filename()); } } @@ -499,7 +499,7 @@ void CommandLineInterface::readInputFiles() m_fileReader.setStdin(readUntilEnd(m_sin)); } - if (m_fileReader.sourceCodes().empty() && !m_standardJsonInput.has_value()) + if (m_fileReader.sourceUnits().empty() && !m_standardJsonInput.has_value()) solThrow(CommandLineValidationError, "All specified input files either do not exist or are not regular files."); } @@ -510,7 +510,7 @@ map CommandLineInterface::parseAstFromInput() map sourceJsons; map tmpSources; - for (SourceCode const& sourceCode: m_fileReader.sourceCodes() | ranges::views::values) + for (SourceCode const& sourceCode: m_fileReader.sourceUnits() | ranges::views::values) { Json::Value ast; astAssert(jsonParseStrict(sourceCode, ast), "Input file could not be parsed to JSON"); @@ -528,7 +528,7 @@ map CommandLineInterface::parseAstFromInput() } } - m_fileReader.setSources(tmpSources); + m_fileReader.setSourceUnits(tmpSources); return sourceJsons; } @@ -721,7 +721,7 @@ void CommandLineInterface::compile() } else { - m_compiler->setSources(m_fileReader.sourceCodes()); + m_compiler->setSources(m_fileReader.sourceUnits()); m_compiler->setParserErrorRecovery(m_options.input.errorRecovery); } @@ -835,7 +835,7 @@ void CommandLineInterface::handleCombinedJSON() if (m_options.compiler.combinedJsonRequests->ast) { output[g_strSources] = Json::Value(Json::objectValue); - for (auto const& sourceCode: m_fileReader.sourceCodes()) + for (auto const& sourceCode: m_fileReader.sourceUnits()) { ASTJsonConverter converter(m_compiler->state(), m_compiler->sourceIndices()); output[g_strSources][sourceCode.first] = Json::Value(Json::objectValue); @@ -858,12 +858,12 @@ void CommandLineInterface::handleAst() return; vector asts; - for (auto const& sourceCode: m_fileReader.sourceCodes()) + for (auto const& sourceCode: m_fileReader.sourceUnits()) asts.push_back(&m_compiler->ast(sourceCode.first)); if (!m_options.output.dir.empty()) { - for (auto const& sourceCode: m_fileReader.sourceCodes()) + for (auto const& sourceCode: m_fileReader.sourceUnits()) { stringstream data; string postfix = ""; @@ -876,7 +876,7 @@ void CommandLineInterface::handleAst() else { sout() << "JSON AST (compact format):" << endl << endl; - for (auto const& sourceCode: m_fileReader.sourceCodes()) + for (auto const& sourceCode: m_fileReader.sourceUnits()) { sout() << endl << "======= " << sourceCode.first << " =======" << endl; ASTJsonConverter(m_compiler->state(), m_compiler->sourceIndices()).print(sout(), m_compiler->ast(sourceCode.first)); @@ -908,7 +908,7 @@ void CommandLineInterface::link() librariesReplacements[replacement] = library.second; } - FileReader::StringMap sourceCodes = m_fileReader.sourceCodes(); + FileReader::StringMap sourceCodes = m_fileReader.sourceUnits(); for (auto& src: sourceCodes) { auto end = src.second.end(); @@ -944,14 +944,14 @@ void CommandLineInterface::link() while (!src.second.empty() && *prev(src.second.end()) == '\n') src.second.resize(src.second.size() - 1); } - m_fileReader.setSources(move(sourceCodes)); + m_fileReader.setSourceUnits(move(sourceCodes)); } void CommandLineInterface::writeLinkedFiles() { solAssert(m_options.input.mode == InputMode::Linker, ""); - for (auto const& src: m_fileReader.sourceCodes()) + for (auto const& src: m_fileReader.sourceUnits()) if (src.first == g_stdinFileName) sout() << src.second << endl; else @@ -989,7 +989,7 @@ void CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul: bool successful = true; map assemblyStacks; - for (auto const& src: m_fileReader.sourceCodes()) + for (auto const& src: m_fileReader.sourceUnits()) { // --no-optimize-yul option is not accepted in assembly mode. solAssert(!m_options.optimizer.noOptimizeYul, ""); @@ -1029,7 +1029,7 @@ void CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul: solThrow(CommandLineExecutionError, ""); } - for (auto const& src: m_fileReader.sourceCodes()) + for (auto const& src: m_fileReader.sourceUnits()) { string machine = _targetMachine == yul::AssemblyStack::Machine::EVM ? "EVM" : @@ -1118,7 +1118,7 @@ void CommandLineInterface::outputCompilationResults() if (m_options.compiler.outputs.asmJson) ret = jsonPrettyPrint(removeNullMembers(m_compiler->assemblyJSON(contract))); else - ret = m_compiler->assemblyString(contract, m_fileReader.sourceCodes()); + ret = m_compiler->assemblyString(contract, m_fileReader.sourceUnits()); if (!m_options.output.dir.empty()) createFile(m_compiler->filesystemFriendlyName(contract) + (m_options.compiler.outputs.asmJson ? "_evm.json" : ".evm"), ret); diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index dbffc47889..494dbbd94d 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -213,7 +213,7 @@ BOOST_AUTO_TEST_CASE(cli_input) BOOST_TEST(result.options.input.mode == InputMode::Compiler); BOOST_TEST(result.options.input.addStdin); BOOST_CHECK_EQUAL(result.options.input.remappings, expectedRemappings); - BOOST_CHECK_EQUAL(result.reader.sourceCodes(), expectedSources); + BOOST_CHECK_EQUAL(result.reader.sourceUnits(), expectedSources); BOOST_CHECK_EQUAL(result.reader.allowedDirectories(), expectedAllowedPaths); } @@ -240,7 +240,7 @@ BOOST_AUTO_TEST_CASE(cli_ignore_missing_some_files_exist) BOOST_TEST(result.stderrContent == "\"" + (tempDir2.path() / "input2.sol").string() + "\" is not found. Skipping.\n"); BOOST_TEST(result.options.input.mode == InputMode::Compiler); BOOST_TEST(!result.options.input.addStdin); - BOOST_CHECK_EQUAL(result.reader.sourceCodes(), expectedSources); + BOOST_CHECK_EQUAL(result.reader.sourceUnits(), expectedSources); BOOST_CHECK_EQUAL(result.reader.allowedDirectories(), expectedAllowedPaths); } @@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(standard_json_base_path) BOOST_TEST(result.options.input.mode == InputMode::StandardJson); BOOST_TEST(result.options.input.addStdin); BOOST_TEST(result.options.input.paths.empty()); - BOOST_TEST(result.reader.sourceCodes().empty()); + BOOST_TEST(result.reader.sourceUnits().empty()); BOOST_TEST(result.reader.allowedDirectories().empty()); BOOST_TEST(result.reader.basePath() == "/" / tempDir.path().relative_path()); } @@ -304,7 +304,7 @@ BOOST_AUTO_TEST_CASE(standard_json_no_input_file) BOOST_TEST(result.options.input.mode == InputMode::StandardJson); BOOST_TEST(result.options.input.addStdin); BOOST_TEST(result.options.input.paths.empty()); - BOOST_TEST(result.reader.sourceCodes().empty()); + BOOST_TEST(result.reader.sourceUnits().empty()); BOOST_TEST(result.reader.allowedDirectories().empty()); } @@ -315,7 +315,7 @@ BOOST_AUTO_TEST_CASE(standard_json_dash) BOOST_TEST(result.stderrContent == ""); BOOST_TEST(result.options.input.mode == InputMode::StandardJson); BOOST_TEST(result.options.input.addStdin); - BOOST_TEST(result.reader.sourceCodes().empty()); + BOOST_TEST(result.reader.sourceUnits().empty()); BOOST_TEST(result.reader.allowedDirectories().empty()); } @@ -446,7 +446,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_no_base_path) BOOST_TEST(result.stdoutContent == ""); BOOST_REQUIRE(result.success); BOOST_TEST(result.options == expectedOptions); - BOOST_TEST(result.reader.sourceCodes() == expectedSources); + BOOST_TEST(result.reader.sourceUnits() == expectedSources); BOOST_TEST(result.reader.allowedDirectories() == expectedAllowedDirectories); BOOST_TEST(result.reader.basePath() == ""); } @@ -508,7 +508,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_base_path_same_as_work_dir) BOOST_TEST(result.stdoutContent == ""); BOOST_REQUIRE(result.success); BOOST_TEST(result.options == expectedOptions); - BOOST_TEST(result.reader.sourceCodes() == expectedSources); + BOOST_TEST(result.reader.sourceUnits() == expectedSources); BOOST_TEST(result.reader.allowedDirectories() == expectedAllowedDirectories); BOOST_TEST(result.reader.basePath() == expectedWorkDir); } @@ -581,7 +581,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_base_path_different_from_wor BOOST_TEST(result.stdoutContent == ""); BOOST_REQUIRE(result.success); BOOST_TEST(result.options == expectedOptions); - BOOST_TEST(result.reader.sourceCodes() == expectedSources); + BOOST_TEST(result.reader.sourceUnits() == expectedSources); BOOST_TEST(result.reader.allowedDirectories() == expectedAllowedDirectories); BOOST_TEST(result.reader.basePath() == expectedBaseDir); } @@ -650,7 +650,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_relative_base_path) BOOST_TEST(result.stdoutContent == ""); BOOST_REQUIRE(result.success); BOOST_TEST(result.options == expectedOptions); - BOOST_TEST(result.reader.sourceCodes() == expectedSources); + BOOST_TEST(result.reader.sourceUnits() == expectedSources); BOOST_TEST(result.reader.allowedDirectories() == expectedAllowedDirectories); BOOST_TEST(result.reader.basePath() == expectedWorkDir / "base"); } @@ -817,7 +817,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_normalization_and_weird_name BOOST_TEST(result.stdoutContent == ""); BOOST_REQUIRE(result.success); BOOST_TEST(result.options == expectedOptions); - BOOST_TEST(result.reader.sourceCodes() == expectedSources); + BOOST_TEST(result.reader.sourceUnits() == expectedSources); BOOST_TEST(result.reader.allowedDirectories() == expectedAllowedDirectories); BOOST_TEST(result.reader.basePath() == expectedOptions.input.basePath); } @@ -874,7 +874,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_symlinks) BOOST_TEST(result.stdoutContent == ""); BOOST_REQUIRE(result.success); BOOST_TEST(result.options == expectedOptions); - BOOST_TEST(result.reader.sourceCodes() == expectedSources); + BOOST_TEST(result.reader.sourceUnits() == expectedSources); BOOST_TEST(result.reader.allowedDirectories() == expectedAllowedDirectories); BOOST_TEST(result.reader.basePath() == expectedWorkDir / "sym/z/"); } @@ -906,7 +906,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_base_path_and_stdin) BOOST_TEST(result.stdoutContent == ""); BOOST_REQUIRE(result.success); BOOST_TEST(result.options == expectedOptions); - BOOST_TEST(result.reader.sourceCodes() == expectedSources); + BOOST_TEST(result.reader.sourceUnits() == expectedSources); BOOST_TEST(result.reader.allowedDirectories() == expectedAllowedDirectories); BOOST_TEST(result.reader.basePath() == expectedWorkDir / "base"); } @@ -1009,7 +1009,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths) BOOST_TEST(result.stdoutContent == ""); BOOST_REQUIRE(result.success); BOOST_TEST(result.options == expectedOptions); - BOOST_TEST(result.reader.sourceCodes() == expectedSources); + BOOST_TEST(result.reader.sourceUnits() == expectedSources); BOOST_TEST(result.reader.includePaths() == expectedIncludePaths); BOOST_TEST(result.reader.allowedDirectories() == expectedAllowedDirectories); BOOST_TEST(result.reader.basePath() == expectedWorkDir / "base/"); @@ -1105,7 +1105,7 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths) BOOST_REQUIRE(result.success); BOOST_TEST(result.options == expectedOptions); - BOOST_TEST(result.reader.sourceCodes() == expectedSources); + BOOST_TEST(result.reader.sourceUnits() == expectedSources); BOOST_TEST(result.reader.includePaths() == expectedIncludePaths); BOOST_TEST(result.reader.allowedDirectories() == expectedAllowedDirectories); BOOST_TEST(result.reader.basePath() == expectedWorkDir / "base/"); From c0b41cfcdd4673e6bff4c0d7b48b3ed4b7a23002 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 13 Dec 2021 17:33:48 +0100 Subject: [PATCH 0190/1748] Add const and file name. --- libsolidity/interface/CompilerStack.cpp | 2 +- libsolidity/interface/FileReader.cpp | 4 ++-- libsolidity/interface/FileReader.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 4b7faf4966..5292d5329f 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1447,7 +1447,7 @@ CompilerStack::Source const& CompilerStack::source(string const& _sourceName) co { auto it = m_sources.find(_sourceName); if (it == m_sources.end()) - solThrow(CompilerError, "Given source file not found."); + solThrow(CompilerError, "Given source file not found: " + _sourceName); return it->second; } diff --git a/libsolidity/interface/FileReader.cpp b/libsolidity/interface/FileReader.cpp index 65cf70e5a4..47f4d2b5aa 100644 --- a/libsolidity/interface/FileReader.cpp +++ b/libsolidity/interface/FileReader.cpp @@ -172,7 +172,7 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so } } -string FileReader::cliPathToSourceUnitName(boost::filesystem::path const& _cliPath) +string FileReader::cliPathToSourceUnitName(boost::filesystem::path const& _cliPath) const { vector prefixes = {m_basePath.empty() ? normalizeCLIPathForVFS(".") : m_basePath}; prefixes += m_includePaths; @@ -189,7 +189,7 @@ string FileReader::cliPathToSourceUnitName(boost::filesystem::path const& _cliPa return normalizedPath.generic_string(); } -map FileReader::detectSourceUnitNameCollisions(FileSystemPathSet const& _cliPaths) +map FileReader::detectSourceUnitNameCollisions(FileSystemPathSet const& _cliPaths) const { map nameToPaths; for (boost::filesystem::path const& cliPath: _cliPaths) diff --git a/libsolidity/interface/FileReader.h b/libsolidity/interface/FileReader.h index 71ca5fc5d1..3892e98263 100644 --- a/libsolidity/interface/FileReader.h +++ b/libsolidity/interface/FileReader.h @@ -93,14 +93,14 @@ class FileReader /// Creates a source unit name by normalizing a path given on the command line and, if possible, /// making it relative to base path or one of the include directories. - std::string cliPathToSourceUnitName(boost::filesystem::path const& _cliPath); + std::string cliPathToSourceUnitName(boost::filesystem::path const& _cliPath) const; /// Checks if a set contains any paths that lead to different files but would receive identical /// source unit names. Files are considered the same if their paths are exactly the same after /// normalization (without following symlinks). /// @returns a map containing all the conflicting source unit names and the paths that would /// receive them. The returned paths are normalized. - std::map detectSourceUnitNameCollisions(FileSystemPathSet const& _cliPaths); + std::map detectSourceUnitNameCollisions(FileSystemPathSet const& _cliPaths) const; /// Normalizes a filesystem path to make it include all components up to the filesystem root, /// remove small, inconsequential differences that do not affect the meaning and make it look From d17f7206ad7ac3e40fc253fa3ece8c3a5eaba718 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Tue, 7 Dec 2021 23:07:19 -0800 Subject: [PATCH 0191/1748] Improve description of break/continue restrictions. This is as discussed on Element, with enhancements discussed with @cameel. --- docs/yul.rst | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/yul.rst b/docs/yul.rst index 219905cd5f..60a2da5b94 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -541,10 +541,24 @@ evaluate to zero values. In all other situations, expressions have to evaluate to exactly one value. -The ``continue`` and ``break`` statements can only be used inside loop bodies -and have to be in the same function as the loop (or both have to be at the -top level). The ``continue`` and ``break`` statements cannot be used -in other parts of a loop, not even when it is scoped inside a second loop's body. +A ``continue`` or ``break`` statement can only be used inside the body of a for-loop, as follows. +Consider the innermost loop that contains the statement. +The loop and the statement must be in the same function, or both must be at the top level. +The statement must be in the loop's body block; +it cannot be in the loop's initialization block or update block. +It is worth emphasizing that this restriction applies just +to the innermost loop that contains the ``continue`` or ``break`` statement: +this innermost loop, and therefore the ``continue`` or ``break`` statement, +may appear anywhere in an outer loop, possibly in an outer loop's initialization block or update block. +For example, the following is legal, +because the ``break`` occurs in the body block of the inner loop, +despite also occurring in the update block of the outer loop: + +.. code-block:: yul + + for {} true { for {} true {} { break } } + { + } The condition part of the for-loop has to evaluate to exactly one value. From 316be7206fa5256443e422cde0de59944fe4d9e7 Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Mon, 13 Dec 2021 22:27:04 +0100 Subject: [PATCH 0192/1748] Fix soundness of storage/memory pointers that were not erasing enough knowledge --- Changelog.md | 1 + libsolidity/formal/SMTEncoder.cpp | 39 +++++++++---------- .../smtCheckerTests/file_level/import.sol | 4 +- .../struct_aliasing_parameter_memory_1.sol | 21 ++++++++++ .../struct_aliasing_parameter_memory_2.sol | 26 +++++++++++++ .../struct_aliasing_parameter_memory_3.sol | 26 +++++++++++++ .../struct_aliasing_parameter_storage_1.sol | 24 ++++++++++++ .../struct_aliasing_parameter_storage_2.sol | 23 +++++++++++ .../struct_aliasing_parameter_storage_3.sol | 29 ++++++++++++++ .../struct_aliasing_parameter_storage_4.sol | 29 ++++++++++++++ .../types/struct/struct_aliasing_storage.sol | 3 +- 11 files changed, 202 insertions(+), 23 deletions(-) create mode 100644 test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_1.sol create mode 100644 test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_2.sol create mode 100644 test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_3.sol create mode 100644 test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_1.sol create mode 100644 test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_2.sol create mode 100644 test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_3.sol create mode 100644 test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_4.sol diff --git a/Changelog.md b/Changelog.md index c5b0481420..f9d7552742 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Compiler Features: Bugfixes: * Code Generator: Fix a crash when using ``@use-src`` and compiling from Yul to ewasm. * SMTChecker: Fix internal error when an unsafe target is solved more than once and the counterexample messages are different. + * SMTChecker: Fix soundness of assigned storage/memory local pointers that were not erasing enough knowledge. * Fix internal error when a function has a calldata struct argument with an internal type inside. diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 11ac5ab7aa..8326b6b2f8 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -32,6 +32,8 @@ #include +#include + #include #include @@ -2371,28 +2373,25 @@ void SMTEncoder::resetReferences(Type const* _type) bool SMTEncoder::sameTypeOrSubtype(Type const* _a, Type const* _b) { - Type const* prefix = _a; - while ( - prefix->category() == Type::Category::Mapping || - prefix->category() == Type::Category::Array - ) - { - if (*typeWithoutPointer(_b) == *typeWithoutPointer(prefix)) - return true; - if (prefix->category() == Type::Category::Mapping) - { - auto mapPrefix = dynamic_cast(prefix); - solAssert(mapPrefix, ""); - prefix = mapPrefix->valueType(); - } - else + bool foundSame = false; + + solidity::util::BreadthFirstSearch bfs{{_a}}; + bfs.run([&](auto _type, auto&& _addChild) { + if (*typeWithoutPointer(_b) == *typeWithoutPointer(_type)) { - auto arrayPrefix = dynamic_cast(prefix); - solAssert(arrayPrefix, ""); - prefix = arrayPrefix->baseType(); + foundSame = true; + bfs.abort(); } - } - return false; + if (auto const* mapType = dynamic_cast(_type)) + _addChild(mapType->valueType()); + else if (auto const* arrayType = dynamic_cast(_type)) + _addChild(arrayType->baseType()); + else if (auto const* structType = dynamic_cast(_type)) + for (auto const& member: structType->nativeMembers(nullptr)) + _addChild(member.type); + }); + + return foundSame; } bool SMTEncoder::isSupportedType(Type const& _type) const diff --git a/test/libsolidity/smtCheckerTests/file_level/import.sol b/test/libsolidity/smtCheckerTests/file_level/import.sol index a67ee4eb6c..85ae712930 100644 --- a/test/libsolidity/smtCheckerTests/file_level/import.sol +++ b/test/libsolidity/smtCheckerTests/file_level/import.sol @@ -22,5 +22,5 @@ contract C { // ==== // SMTEngine: all // ---- -// Warning 6328: (B:238-252): CHC: Assertion violation happens here.\nCounterexample:\ndata = {x: 0}\nx = 0\ny = 0\n\nTransaction trace:\nC.constructor()\nState: data = {x: 0}\nC.g()\n C.f(7) -- internal call\n A:set({x: 0}, 7) -- internal call\n A:set({x: 0}, 8) -- internal call -// Warning 6328: (B:308-322): CHC: Assertion violation happens here.\nCounterexample:\ndata = {x: 0}\nx = 0\ny = 0\n\nTransaction trace:\nC.constructor()\nState: data = {x: 0}\nC.g()\n C.f(7) -- internal call\n A:set({x: 0}, 7) -- internal call\n A:set({x: 0}, 8) -- internal call +// Warning 6328: (B:238-252): CHC: Assertion violation happens here.\nCounterexample:\ndata = {x: 21238}\nx = 8\ny = 21238\n\nTransaction trace:\nC.constructor()\nState: data = {x: 0}\nC.g()\n C.f(7) -- internal call\n A:set({x: 0}, 7) -- internal call\n A:set({x: 8}, 8) -- internal call +// Warning 6328: (B:308-322): CHC: Assertion violation happens here.\nCounterexample:\ndata = {x: 6}\nx = 0\ny = 6\n\nTransaction trace:\nC.constructor()\nState: data = {x: 0}\nC.g()\n C.f(7) -- internal call\n A:set({x: 0}, 7) -- internal call\n A:set({x: 0}, 8) -- internal call diff --git a/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_1.sol b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_1.sol new file mode 100644 index 0000000000..edb1e1b40b --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_1.sol @@ -0,0 +1,21 @@ +contract C { + struct S { + uint sum; + uint[] a; + } + + function f(S memory m, uint v) internal pure { + m.sum = v; + m.a = new uint[](2); + } + + constructor(uint amt) { + S memory s; + f(s, amt); + assert(s.a.length == 2); // should hold but no aliasing support means it fails for now + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6328: (201-224): CHC: Assertion violation happens here.\nCounterexample:\n\namt = 0\ns = {sum: 0, a: []}\n\nTransaction trace:\nC.constructor(0) diff --git a/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_2.sol b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_2.sol new file mode 100644 index 0000000000..28da837006 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_2.sol @@ -0,0 +1,26 @@ +contract C { + struct S { + uint sum; + uint[] a; + } + + struct T { + S s; + uint x; + } + + function f(S memory m, uint v) internal pure { + m.sum = v; + m.a = new uint[](2); + } + + constructor(uint amt) { + T memory t; + f(t.s, amt); + assert(t.s.a.length == 2); // should hold but no aliasing support means it fails for now + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6328: (236-261): CHC: Assertion violation happens here.\nCounterexample:\n\namt = 0\nt = {s: {sum: 0, a: []}, x: 0}\n\nTransaction trace:\nC.constructor(0) diff --git a/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_3.sol b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_3.sol new file mode 100644 index 0000000000..36890f03eb --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_3.sol @@ -0,0 +1,26 @@ +contract C { + struct S { + uint sum; + uint[] a; + } + + struct T { + S s; + uint x; + } + + function f(T memory m, uint v) internal pure { + m.s.sum = v; + m.s.a = new uint[](2); + } + + constructor(uint amt) { + T memory t; + f(t, amt); + assert(t.s.a.length == 2); // should hold but no aliasing support means it fails for now + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6328: (238-263): CHC: Assertion violation happens here.\nCounterexample:\n\namt = 0\nt = {s: {sum: 0, a: []}, x: 0}\n\nTransaction trace:\nC.constructor(0) diff --git a/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_1.sol b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_1.sol new file mode 100644 index 0000000000..3fd0c0d873 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_1.sol @@ -0,0 +1,24 @@ +contract C { + struct S { + mapping(address => uint) innerM; + uint sum; + } + + function f(S storage m, address i, uint v) internal { + m.innerM[i] = v; + m.sum += v; + } + + S s; + + constructor(uint amt) { + f(s, msg.sender, amt); + } + function g() public view { + assert(s.sum == 0); // should hold but no aliasing support means it fails for now + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6328: (270-288): CHC: Assertion violation happens here.\nCounterexample:\ns = {innerM, sum: 21239}\n\nTransaction trace:\nC.constructor(0){ msg.sender: 0x6dc4 }\nState: s = {innerM, sum: 21239}\nC.g() diff --git a/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_2.sol b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_2.sol new file mode 100644 index 0000000000..9d4623ae09 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_2.sol @@ -0,0 +1,23 @@ +contract C { + struct S { + mapping(address => uint) innerM; + uint sum; + } + + function f(mapping(address => uint) storage innerM, address i, uint v) internal { + innerM[i] = v; + } + + S s; + + constructor(uint amt) { + f(s.innerM, msg.sender, amt); + } + function g() public view { + assert(s.innerM[msg.sender] == 0); // should hold but no aliasing support means it fails for now + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6328: (289-322): CHC: Assertion violation happens here.\nCounterexample:\ns = {innerM, sum: 10}\n\nTransaction trace:\nC.constructor(0){ msg.sender: 0x6dc4 }\nState: s = {innerM, sum: 10}\nC.g(){ msg.sender: 0x0985 } diff --git a/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_3.sol b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_3.sol new file mode 100644 index 0000000000..8779cd0959 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_3.sol @@ -0,0 +1,29 @@ +contract C { + struct S { + mapping(address => uint) innerM; + uint sum; + } + + struct T { + uint x; + S s; + } + + function f(T storage m, address i, uint v) internal { + m.s.innerM[i] = v; + m.s.sum += v; + } + + T t; + + constructor(uint amt) { + f(t, msg.sender, amt); + } + function g() public view { + assert(t.s.sum == 0); // should hold but no aliasing support means it fails for now + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6328: (307-327): CHC: Assertion violation happens here.\nCounterexample:\nt = {x: 10, s: {innerM, sum: 21239}}\n\nTransaction trace:\nC.constructor(0){ msg.sender: 0x6dc4 }\nState: t = {x: 10, s: {innerM, sum: 21239}}\nC.g() diff --git a/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_4.sol b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_4.sol new file mode 100644 index 0000000000..957c72c120 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_4.sol @@ -0,0 +1,29 @@ +contract C { + struct S { + mapping(address => uint) innerM; + uint sum; + } + + struct T { + uint x; + S s; + } + + function f(S storage m, address i, uint v) internal { + m.innerM[i] = v; + m.sum += v; + } + + T t; + + constructor(uint amt) { + f(t.s, msg.sender, amt); + } + function g() public view { + assert(t.s.sum == 0); // should hold but no aliasing support means it fails for now + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6328: (305-325): CHC: Assertion violation happens here.\nCounterexample:\nt = {x: 10, s: {innerM, sum: 21239}}\n\nTransaction trace:\nC.constructor(0){ msg.sender: 0x6dc4 }\nState: t = {x: 10, s: {innerM, sum: 21239}}\nC.g() diff --git a/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_storage.sol b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_storage.sol index 4c13699e2f..e5d9d60abe 100644 --- a/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_storage.sol +++ b/test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_storage.sol @@ -25,5 +25,6 @@ contract C { } // ==== // SMTEngine: all +// SMTIgnoreCex: yes // ---- -// Warning 6328: (369-405): CHC: Assertion violation happens here.\nCounterexample:\ns1 = {x: 0, a: []}, s2 = {x: 0, a: []}\nb = false\ns3 = {x: 42, a: []}\n\nTransaction trace:\nC.constructor()\nState: s1 = {x: 0, a: []}, s2 = {x: 0, a: []}\nC.f(false) +// Warning 6328: (369-405): CHC: Assertion violation happens here. From 91ee0ed4ef07f0f376b0c0cc74050925dc9b5942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 9 Dec 2021 14:10:14 +0100 Subject: [PATCH 0193/1748] scripts/common.sh: Add first_word() helper --- scripts/common.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/common.sh b/scripts/common.sh index 3e67c4f566..ab7d82d875 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -226,7 +226,16 @@ function circleci_step_selected { local selected_steps="$1" local step="$2" + (( $# == 2 )) || assertFail [[ $step != *" "* ]] || assertFail "Step names must not contain spaces." [[ " $selected_steps " == *" $step "* ]] || return 1 } + +function first_word +{ + local words="$1" + (( $# == 1 )) || assertFail + + echo "$words" | cut -d " " -f 1 +} From adfa51c01c89fd406a8b1ab8c24a606bcec48d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 29 Nov 2021 14:20:42 +0100 Subject: [PATCH 0194/1748] externalTests: Measure compilation time --- test/externalTests/common.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 80a9dec32c..0f5bbc0b11 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -236,7 +236,7 @@ function run_test replace_version_pragmas printLog "Running compile function..." - $compile_fn + time $compile_fn printLog "Running test function..." $test_fn @@ -329,7 +329,7 @@ function compile_and_run_test local verify_fn="$3" printLog "Running compile function..." - $compile_fn + time $compile_fn $verify_fn "$SOLCVERSION_SHORT" "$SOLCVERSION" if [[ "$COMPILE_ONLY" == 1 ]]; then From d304c8443218753acabd16535ee883ab92e0a88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 9 Dec 2021 14:37:21 +0100 Subject: [PATCH 0195/1748] externalTests: Replace optimizer levels with named presets --- scripts/common.sh | 7 ++++ test/externalTests/colony.sh | 20 ++++++----- test/externalTests/common.sh | 63 ++++++++++++++++----------------- test/externalTests/ens.sh | 19 +++++----- test/externalTests/gnosis-v2.sh | 20 ++++++----- test/externalTests/gnosis.sh | 20 ++++++----- test/externalTests/zeppelin.sh | 19 +++++----- 7 files changed, 92 insertions(+), 76 deletions(-) diff --git a/scripts/common.sh b/scripts/common.sh index ab7d82d875..4a98c00726 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -211,6 +211,7 @@ function safe_kill function circleci_select_steps { + # We expect multiple lines in $all_steps, one step per line local all_steps="$1" (( $# == 1 )) || assertFail @@ -222,6 +223,12 @@ function circleci_select_steps fi } +function circleci_select_steps_multiarg +{ + # We expect multiple arguments, one step per argument. + circleci_select_steps "$(printf '%s\n' "$@")" +} + function circleci_step_selected { local selected_steps="$1" diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 65a2183bcc..7326f90bc7 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -36,20 +36,22 @@ function colony_test local repo="https://github.com/solidity-external-tests/colonyNetwork.git" local branch=develop_080 local config_file="truffle.js" - # On levels 1 and 2 it compiles but tests run out of gas - local min_optimizer_level=3 - local max_optimizer_level=3 + local settings_presets=( + #legacy-no-optimize # Compiles but tests run out of gas + #legacy-optimize-evm-only # Compiles but tests run out of gas + legacy-optimize-evm+yul + ) - local selected_optimizer_levels - selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") - print_optimizer_levels_or_exit "$selected_optimizer_levels" + local selected_optimizer_presets + selected_optimizer_presets=$(circleci_select_steps_multiarg "${settings_presets[@]}") + print_optimizer_presets_or_exit "$selected_optimizer_presets" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" [[ $BINARY_TYPE == native ]] && replace_global_solc "$BINARY_PATH" neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$min_optimizer_level" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$(first_word "$selected_optimizer_presets")" yarn install git submodule update --init @@ -61,8 +63,8 @@ function colony_test replace_version_pragmas [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" - for level in $selected_optimizer_levels; do - truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$level" compile_fn test_fn + for preset in $selected_optimizer_presets; do + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$preset" compile_fn test_fn done } diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 0f5bbc0b11..93484b16b3 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -24,13 +24,13 @@ set -e CURRENT_EVM_VERSION=london -function print_optimizer_levels_or_exit +function print_optimizer_presets_or_exit { - local selected_levels="$1" + local selected_presets="$1" - [[ $selected_levels != "" ]] || { printWarning "No steps to run. Exiting."; exit 0; } + [[ $selected_presets != "" ]] || { printWarning "No presets to run. Exiting."; exit 0; } - printLog "Selected optimizer levels: ${selected_levels}" + printLog "Selected settings presets: ${selected_presets}" } function verify_input @@ -141,7 +141,7 @@ function force_truffle_compiler_settings local config_file="$1" local binary_type="$2" local solc_path="$3" - local level="$4" + local preset="$4" local evm_version="${5:-"$CURRENT_EVM_VERSION"}" [[ $binary_type == native || $binary_type == solcjs ]] || assertFail @@ -153,14 +153,16 @@ function force_truffle_compiler_settings echo "Config file: $config_file" echo "Binary type: $binary_type" echo "Compiler path: $solc_path" - echo "Optimization level: $level" - echo "Optimizer settings: $(optimizer_settings_for_level "$level")" + echo "Settings preset: ${preset}" + echo "Settings: $(settings_from_preset "$preset" "$evm_version")" echo "EVM version: $evm_version" + echo "Compiler version: ${SOLCVERSION_SHORT}" + echo "Compiler version (full): ${SOLCVERSION}" echo "-------------------------------------" # Forcing the settings should always work by just overwriting the solc object. Forcing them by using a # dedicated settings objects should only be the fallback. - echo "module.exports['compilers'] = $(truffle_compiler_settings "$solc_path" "$level" "$evm_version");" >> "$config_file" + echo "module.exports['compilers'] = $(truffle_compiler_settings "$solc_path" "$preset" "$evm_version");" >> "$config_file" } function force_hardhat_compiler_binary @@ -180,14 +182,14 @@ function force_hardhat_compiler_binary function force_hardhat_compiler_settings { local config_file="$1" - local level="$2" + local preset="$2" local evm_version="${3:-"$CURRENT_EVM_VERSION"}" printLog "Configuring Hardhat..." echo "-------------------------------------" echo "Config file: ${config_file}" - echo "Optimization level: ${level}" - echo "Optimizer settings: $(optimizer_settings_for_level "$level")" + echo "Settings preset: ${preset}" + echo "Settings: $(settings_from_preset "$preset" "$evm_version")" echo "EVM version: ${evm_version}" echo "Compiler version: ${SOLCVERSION_SHORT}" echo "Compiler version (full): ${SOLCVERSION}" @@ -195,7 +197,7 @@ function force_hardhat_compiler_settings { echo -n 'module.exports["solidity"] = ' - hardhat_compiler_settings "$SOLCVERSION_SHORT" "$level" "$evm_version" + hardhat_compiler_settings "$SOLCVERSION_SHORT" "$preset" "$evm_version" } >> "$config_file" } @@ -242,16 +244,17 @@ function run_test $test_fn } -function optimizer_settings_for_level +function settings_from_preset { - local level="$1" + local preset="$1" + local evm_version="$2" - case "$level" in - 1) echo "{enabled: false}" ;; - 2) echo "{enabled: true, details: {yul: false}}" ;; - 3) echo "{enabled: true, details: {yul: true}}" ;; + case "$preset" in + legacy-no-optimize) echo "{evmVersion: '${evm_version}', optimizer: {enabled: false}}" ;; + legacy-optimize-evm-only) echo "{evmVersion: '${evm_version}', optimizer: {enabled: true, details: {yul: false}}}" ;; + legacy-optimize-evm+yul) echo "{evmVersion: '${evm_version}', optimizer: {enabled: true, details: {yul: true}}}" ;; *) - fail "Optimizer level not found. Please define OPTIMIZER_LEVEL=[1, 2, 3]" + fail "Unknown settings preset: '${preset}'." ;; esac } @@ -269,16 +272,13 @@ function replace_global_solc function truffle_compiler_settings { local solc_path="$1" - local level="$2" + local preset="$2" local evm_version="$3" echo "{" echo " solc: {" echo " version: \"${solc_path}\"," - echo " settings: {" - echo " optimizer: $(optimizer_settings_for_level "$level")," - echo " evmVersion: \"${evm_version}\"" - echo " }" + echo " settings: $(settings_from_preset "$preset" "$evm_version")" echo " }" echo "}" } @@ -310,15 +310,12 @@ function hardhat_solc_build_subtask { function hardhat_compiler_settings { local solc_version="$1" - local level="$2" + local preset="$2" local evm_version="$3" echo "{" echo " version: '${solc_version}'," - echo " settings: {" - echo " optimizer: $(optimizer_settings_for_level "$level")," - echo " evmVersion: '${evm_version}'" - echo " }" + echo " settings: $(settings_from_preset "$preset" "$evm_version")" echo "}" } @@ -345,24 +342,24 @@ function truffle_run_test local config_file="$1" local binary_type="$2" local solc_path="$3" - local optimizer_level="$4" + local preset="$4" local compile_fn="$5" local test_fn="$6" truffle_clean - force_truffle_compiler_settings "$config_file" "$binary_type" "$solc_path" "$optimizer_level" + force_truffle_compiler_settings "$config_file" "$binary_type" "$solc_path" "$preset" compile_and_run_test compile_fn test_fn truffle_verify_compiler_version } function hardhat_run_test { local config_file="$1" - local optimizer_level="$2" + local preset="$2" local compile_fn="$3" local test_fn="$4" hardhat_clean - force_hardhat_compiler_settings "$config_file" "$optimizer_level" + force_hardhat_compiler_settings "$config_file" "$preset" compile_and_run_test compile_fn test_fn hardhat_verify_compiler_version } diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index 7b354acde6..de05454312 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -36,12 +36,15 @@ function ens_test local repo="https://github.com/ensdomains/ens.git" local branch=master local config_file="truffle.js" - local min_optimizer_level=1 - local max_optimizer_level=3 + local settings_presets=( + legacy-no-optimize + legacy-optimize-evm-only + legacy-optimize-evm+yul + ) - local selected_optimizer_levels - selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") - print_optimizer_levels_or_exit "$selected_optimizer_levels" + local selected_optimizer_presets + selected_optimizer_presets=$(circleci_select_steps_multiarg "${settings_presets[@]}") + print_optimizer_presets_or_exit "$selected_optimizer_presets" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" @@ -52,14 +55,14 @@ function ens_test neutralize_package_lock neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$min_optimizer_level" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$(first_word "$selected_optimizer_presets")" npm install replace_version_pragmas [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" - for level in $selected_optimizer_levels; do - truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$level" compile_fn test_fn + for preset in $selected_optimizer_presets; do + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$preset" compile_fn test_fn done } diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index b71749a065..443d5583cb 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -36,13 +36,15 @@ function gnosis_safe_test local repo="https://github.com/solidity-external-tests/safe-contracts.git" local branch=v2_080 local config_file="truffle-config.js" - # level 1: "Error: while migrating GnosisSafe: Returned error: base fee exceeds gas limit" - local min_optimizer_level=2 - local max_optimizer_level=3 + local settings_presets=( + #legacy-no-optimize # "Error: while migrating GnosisSafe: Returned error: base fee exceeds gas limit" + legacy-optimize-evm-only + legacy-optimize-evm+yul + ) - local selected_optimizer_levels - selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") - print_optimizer_levels_or_exit "$selected_optimizer_levels" + local selected_optimizer_presets + selected_optimizer_presets=$(circleci_select_steps_multiarg "${settings_presets[@]}") + print_optimizer_presets_or_exit "$selected_optimizer_presets" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" @@ -53,14 +55,14 @@ function gnosis_safe_test neutralize_package_lock neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$min_optimizer_level" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$(first_word "$selected_optimizer_presets")" npm install --package-lock replace_version_pragmas [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" - for level in $selected_optimizer_levels; do - truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$level" compile_fn test_fn + for preset in $selected_optimizer_presets; do + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$preset" compile_fn test_fn done } diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 97208660bc..9f0d356b6c 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -36,13 +36,15 @@ function gnosis_safe_test local repo="https://github.com/solidity-external-tests/safe-contracts.git" local branch=development_080 local config_file="truffle-config.js" - # levels 1 and 2: "Stack too deep" error - local min_optimizer_level=3 - local max_optimizer_level=3 + local settings_presets=( + #legacy-no-optimize # "Stack too deep" error + #legacy-optimize-evm-only # "Stack too deep" error + legacy-optimize-evm+yul + ) - local selected_optimizer_levels - selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") - print_optimizer_levels_or_exit "$selected_optimizer_levels" + local selected_optimizer_presets + selected_optimizer_presets=$(circleci_select_steps_multiarg "${settings_presets[@]}") + print_optimizer_presets_or_exit "$selected_optimizer_presets" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" @@ -52,14 +54,14 @@ function gnosis_safe_test neutralize_package_lock neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$min_optimizer_level" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$(first_word "$selected_optimizer_presets")" npm install --package-lock replace_version_pragmas [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" - for level in $selected_optimizer_levels; do - truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$level" compile_fn test_fn + for preset in $selected_optimizer_presets; do + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$preset" compile_fn test_fn done } diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 0759a3aec6..280c9ffeba 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -36,25 +36,28 @@ function zeppelin_test local repo="https://github.com/OpenZeppelin/openzeppelin-contracts.git" local branch=master local config_file="hardhat.config.js" - local min_optimizer_level=1 - local max_optimizer_level=3 + local settings_presets=( + legacy-no-optimize + legacy-optimize-evm-only + legacy-optimize-evm+yul + ) - local selected_optimizer_levels - selected_optimizer_levels=$(circleci_select_steps "$(seq "$min_optimizer_level" "$max_optimizer_level")") - print_optimizer_levels_or_exit "$selected_optimizer_levels" + local selected_optimizer_presets + selected_optimizer_presets=$(circleci_select_steps_multiarg "${settings_presets[@]}") + print_optimizer_presets_or_exit "$selected_optimizer_presets" setup_solc "$DIR" "$BINARY_TYPE" "$BINARY_PATH" download_project "$repo" "$branch" "$DIR" neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" - force_hardhat_compiler_settings "$config_file" "$min_optimizer_level" + force_hardhat_compiler_settings "$config_file" "$(first_word "$selected_optimizer_presets")" npm install replace_version_pragmas - for level in $selected_optimizer_levels; do - hardhat_run_test "$config_file" "$level" compile_fn test_fn + for preset in $selected_optimizer_presets; do + hardhat_run_test "$config_file" "$preset" compile_fn test_fn done } From 3ec05d02b5abeac390bc074b523f2c77c3aafa81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 9 Dec 2021 15:35:16 +0100 Subject: [PATCH 0196/1748] externalTests: Add extra viaIR runs --- .circleci/config.yml | 5 +++-- test/externalTests/colony.sh | 3 +++ test/externalTests/common.sh | 10 +++++++--- test/externalTests/ens.sh | 3 +++ test/externalTests/gnosis-v2.sh | 3 +++ test/externalTests/gnosis.sh | 3 +++ test/externalTests/zeppelin.sh | 3 +++ 7 files changed, 25 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cda6e58909..20d06662d8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1037,8 +1037,9 @@ jobs: docker: - image: circleci/node:<> resource_class: <> - # NOTE: Each external test does 3 separate compile&test runs - parallelism: 3 + # NOTE: Each external test runs up to 6 independent settings presets. If parallelism is higher than + # actual preset count, some runs will exit immediately. If it's lower, some runs will get more than one preset. + parallelism: 6 environment: TERM: xterm COMPILE_ONLY: <> diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 7326f90bc7..d5b57f024a 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -37,6 +37,9 @@ function colony_test local branch=develop_080 local config_file="truffle.js" local settings_presets=( + #ir-no-optimize # Compiles but tests run out of gas + #ir-optimize-evm-only # Compiles but tests run out of gas + ir-optimize-evm+yul #legacy-no-optimize # Compiles but tests run out of gas #legacy-optimize-evm-only # Compiles but tests run out of gas legacy-optimize-evm+yul diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 93484b16b3..012a21b2f7 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -250,9 +250,13 @@ function settings_from_preset local evm_version="$2" case "$preset" in - legacy-no-optimize) echo "{evmVersion: '${evm_version}', optimizer: {enabled: false}}" ;; - legacy-optimize-evm-only) echo "{evmVersion: '${evm_version}', optimizer: {enabled: true, details: {yul: false}}}" ;; - legacy-optimize-evm+yul) echo "{evmVersion: '${evm_version}', optimizer: {enabled: true, details: {yul: true}}}" ;; + # NOTE: Remember to update `parallelism` of `t_ems_ext` job in CI config if you add/remove presets + legacy-no-optimize) echo "{evmVersion: '${evm_version}', viaIR: false, optimizer: {enabled: false}}" ;; + ir-no-optimize) echo "{evmVersion: '${evm_version}', viaIR: true, optimizer: {enabled: false}}" ;; + legacy-optimize-evm-only) echo "{evmVersion: '${evm_version}', viaIR: false, optimizer: {enabled: true, details: {yul: false}}}" ;; + ir-optimize-evm-only) echo "{evmVersion: '${evm_version}', viaIR: true, optimizer: {enabled: true, details: {yul: false}}}" ;; + legacy-optimize-evm+yul) echo "{evmVersion: '${evm_version}', viaIR: false, optimizer: {enabled: true, details: {yul: true}}}" ;; + ir-optimize-evm+yul) echo "{evmVersion: '${evm_version}', viaIR: true, optimizer: {enabled: true, details: {yul: true}}}" ;; *) fail "Unknown settings preset: '${preset}'." ;; diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index de05454312..c0bc4b558c 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -37,6 +37,9 @@ function ens_test local branch=master local config_file="truffle.js" local settings_presets=( + #ir-no-optimize # "YulException: Variable var_ttl_236 is 1 slot(s) too deep inside the stack." + #ir-optimize-evm-only # "YulException: Variable var_ttl_236 is 1 slot(s) too deep inside the stack." + ir-optimize-evm+yul legacy-no-optimize legacy-optimize-evm-only legacy-optimize-evm+yul diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 443d5583cb..bae0f0f1e6 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -37,6 +37,9 @@ function gnosis_safe_test local branch=v2_080 local config_file="truffle-config.js" local settings_presets=( + #ir-no-optimize # "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." + #ir-optimize-evm-only # "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." + ir-optimize-evm+yul #legacy-no-optimize # "Error: while migrating GnosisSafe: Returned error: base fee exceeds gas limit" legacy-optimize-evm-only legacy-optimize-evm+yul diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 9f0d356b6c..562ab156f6 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -37,6 +37,9 @@ function gnosis_safe_test local branch=development_080 local config_file="truffle-config.js" local settings_presets=( + #ir-no-optimize # "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." + #ir-optimize-evm-only # "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." + ir-optimize-evm+yul #legacy-no-optimize # "Stack too deep" error #legacy-optimize-evm-only # "Stack too deep" error legacy-optimize-evm+yul diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 280c9ffeba..89f3d6b423 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -37,6 +37,9 @@ function zeppelin_test local branch=master local config_file="hardhat.config.js" local settings_presets=( + #ir-no-optimize # "YulException: Variable var_account_852 is 4 slot(s) too deep inside the stack." + #ir-optimize-evm-only # "YulException: Variable var_account_852 is 4 slot(s) too deep inside the stack." + #ir-optimize-evm+yul # Compiles but tests fail. See https://github.com/nomiclabs/hardhat/issues/2115 legacy-no-optimize legacy-optimize-evm-only legacy-optimize-evm+yul From c15ef45d2969c6a53216c27126294b940e761583 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 6 Dec 2021 15:52:50 +0100 Subject: [PATCH 0197/1748] Explanation about operators. --- docs/types/operators.rst | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/docs/types/operators.rst b/docs/types/operators.rst index 29962588fe..450963e11d 100644 --- a/docs/types/operators.rst +++ b/docs/types/operators.rst @@ -1,7 +1,35 @@ -.. index:: assignment, ! delete, lvalue +.. index:: ! operator -Operators Involving LValues -=========================== +Operators +========= + +Arithmetic and bit operators can be applied even if the two operands do not have the same type. +For example, you can compute ``y = x + z``, where ``x`` is a ``uint8`` and ``z`` has +the type ``int32``. In these cases, the following mechanism will be used to determine +the type in which the operation is computed (this is important in case of overflow) +and the type of the operator's result: + +1. If the type of the right operand can be implicitly converted to the type of the left + operand, use the type of the left operand, +2. if the type of the left operand can be implicitly converted to the type of the right + operand, use the type of the right operand, +3. otherwise, the operation is not allowed. + +In case one of the operands is a :ref:`literal number ` it is first converted to its +"mobile type", which is the smallest type that can hold the value +(unsigned types of the same bit-width are considered "smaller" than the signed types). +If both are literal numbers, the operation is computed with arbitrary precision. + +The operator's result type is the same as the type the operation is performed in, +except for comparison operators where the result is always ``bool``. + +The operators ``**`` (exponentiation), ``<<`` and ``>>`` use the type of the +left operand for the operation and the result. + +.. index:: assignment, lvalue, ! compound operators + +Compound and Increment/Decrement Operators +------------------------------------------ If ``a`` is an LValue (i.e. a variable or something that can be assigned to), the following operators are available as shorthands: @@ -12,6 +40,8 @@ to ``a += 1`` / ``a -= 1`` but the expression itself still has the previous valu of ``a``. In contrast, ``--a`` and ``++a`` have the same effect on ``a`` but return the value after the change. +.. index:: !delete + .. _delete: delete From 9b55d4788e5e008905af060b26f44cac7e45d98e Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Mon, 6 Dec 2021 18:01:27 +0530 Subject: [PATCH 0198/1748] Added sameType check for fromType and toType in YulUtilFunctions.cpp and relevant tests in semanticTests --- Changelog.md | 2 +- libsolidity/codegen/YulUtilFunctions.cpp | 11 ++++- ...on_external_storage_to_storage_dynamic.sol | 43 ++++++++++++++++++ ...o_storage_dynamic_different_mutability.sol | 45 +++++++++++++++++++ ... copy_function_internal_storage_array.sol} | 2 +- .../copy_storage_arrays_of_function_type.sol | 9 ++++ 6 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol create mode 100644 test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol rename test/libsolidity/semanticTests/array/copying/{copy_function_storage_array.sol => copy_function_internal_storage_array.sol} (94%) create mode 100644 test/libsolidity/syntaxTests/array/copy_storage_arrays_of_function_type.sol diff --git a/Changelog.md b/Changelog.md index f9d7552742..c4b67e935b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,7 +11,7 @@ Bugfixes: * SMTChecker: Fix internal error when an unsafe target is solved more than once and the counterexample messages are different. * SMTChecker: Fix soundness of assigned storage/memory local pointers that were not erasing enough knowledge. * Fix internal error when a function has a calldata struct argument with an internal type inside. - + * IR Generator: Fix IR syntax error when copying storage arrays of functions. ### 0.8.10 (2021-11-09) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 1ad9aafa7f..106ad260f9 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -2057,7 +2057,7 @@ string YulUtilFunctions::copyValueArrayStorageToStorageFunction(ArrayType const& solAssert(!_fromType.isValueType(), ""); templ("functionName", functionName); templ("resizeArray", resizeArrayFunction(_toType)); - templ("arrayLength",arrayLengthFunction(_fromType)); + templ("arrayLength", arrayLengthFunction(_fromType)); templ("panic", panicFunction(PanicCode::ResourceError)); templ("srcDataLocation", arrayDataAreaFunction(_fromType)); templ("dstDataLocation", arrayDataAreaFunction(_toType)); @@ -2065,7 +2065,14 @@ string YulUtilFunctions::copyValueArrayStorageToStorageFunction(ArrayType const& unsigned itemsPerSlot = 32 / _toType.storageStride(); templ("itemsPerSlot", to_string(itemsPerSlot)); templ("multipleItemsPerSlotDst", itemsPerSlot > 1); - bool sameType = _fromType.baseType() == _toType.baseType(); + bool sameType = *_fromType.baseType() == *_toType.baseType(); + if (auto functionType = dynamic_cast(_fromType.baseType())) + { + solAssert(functionType->equalExcludingStateMutability( + dynamic_cast(*_toType.baseType()) + )); + sameType = true; + } templ("sameType", sameType); if (sameType) { 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 new file mode 100644 index 0000000000..543342dfde --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol @@ -0,0 +1,43 @@ +contract C { + function testFunction1() public {} + function testFunction2() public {} + function testFunction3() public {} + + + function() external [3] externalArray0; + function() external [3] externalArray1 = [ + this.testFunction1, + this.testFunction2, + this.testFunction3 + ]; + + function copyExternalStorageArrayOfFunctionType() external returns (bool) { + assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1))); + externalArray0 = externalArray1; + return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1)); + } + + function() internal [3] internalArray0; + function() internal [3] internalArray1 = [ + testFunction1, + testFunction2, + testFunction3 + ]; + + function copyInternalArrayOfFunctionType() external returns (bool) { + internalArray0 = internalArray1; + assert(internalArray0.length == 3); + + return + internalArray0.length == internalArray1.length && + internalArray0[0] == internalArray1[0] && + internalArray0[1] == internalArray1[1] && + internalArray0[2] == internalArray1[2]; + } +} +// ==== +// compileViaYul: also +// ---- +// copyExternalStorageArrayOfFunctionType() -> true +// gas legacy: 103412 +// 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 new file mode 100644 index 0000000000..0e356bce65 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol @@ -0,0 +1,45 @@ +contract C { + function testFunction1() public {} + function testFunction2() public view {} + function testFunction3() public pure {} + + function() external [3] externalArray0; + function() external [3] externalArray1 = [ + this.testFunction1, + this.testFunction2, + this.testFunction3 + ]; + + function copyExternalStorageArraysOfFunctionType() external returns (bool) + { + assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1))); + externalArray0 = externalArray1; + return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1)); + } + + function() internal [3] internalArray0; + function() internal [3] internalArray1 = [ + testFunction1, + testFunction2, + testFunction3 + ]; + + function copyInternalArrayOfFunctionType() external returns (bool) + { + internalArray0 = internalArray1; + assert(internalArray0.length == 3); + + return + internalArray0.length == internalArray1.length && + internalArray0[0] == internalArray1[0] && + internalArray0[1] == internalArray1[1] && + internalArray0[2] == internalArray1[2]; + } +} +// ==== +// compileViaYul: also +// ---- +// copyExternalStorageArraysOfFunctionType() -> true +// gas legacy: 103398 +// copyInternalArrayOfFunctionType() -> true +// gas legacy: 104178 diff --git a/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol b/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol similarity index 94% rename from test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol rename to test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol index 8448d2e69b..6f019c77c2 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol @@ -18,6 +18,6 @@ contract C { // compileViaYul: also // ---- // test() -> 7 -// gas irOptimized: 126552 +// gas irOptimized: 124080 // gas legacy: 205196 // gas legacyOptimized: 204987 diff --git a/test/libsolidity/syntaxTests/array/copy_storage_arrays_of_function_type.sol b/test/libsolidity/syntaxTests/array/copy_storage_arrays_of_function_type.sol new file mode 100644 index 0000000000..44011bea45 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/copy_storage_arrays_of_function_type.sol @@ -0,0 +1,9 @@ +contract C { + function() external [] s0; + function() external view [] s1; + function copyStorageArrayOfFunctionType() public { + s1 = s0; + } +} +// ---- +// TypeError 7407: (148-150): Type function () external[] storage ref is not implicitly convertible to expected type function () view external[] storage ref. From fdeb9717084e7427100b7ec5778c8a1ab222f5f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 15 Dec 2021 20:45:39 +0100 Subject: [PATCH 0199/1748] Add an appropriate label to each type of issue --- .github/ISSUE_TEMPLATE/bug_report.md | 1 + .github/ISSUE_TEMPLATE/documentation_issue.md | 1 + .github/ISSUE_TEMPLATE/feature_request.md | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 571b97474c..0edc9f79f0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,7 @@ --- name: Bug Report about: Bug reports about the Solidity Compiler. +labels: ["bug :bug:"] --- ## Description diff --git a/.github/ISSUE_TEMPLATE/documentation_issue.md b/.github/ISSUE_TEMPLATE/documentation_issue.md index fc3dd77dbb..c5873f726c 100644 --- a/.github/ISSUE_TEMPLATE/documentation_issue.md +++ b/.github/ISSUE_TEMPLATE/documentation_issue.md @@ -6,18 +6,12 @@ labels: ["documentation :book:"] ## Page - + ## Abstract - + ## Pull request - + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 0b86a08f4f..7191414d43 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -9,40 +9,29 @@ labels: ["feature"] - First, many thanks for taking part in the community. We really appreciate that. - We realize there is a lot of data requested here. We ask only that you do your best to provide as much information as possible so we can better help you. - Support questions are better asked in one of the following locations: - - [Solidity chat](https://gitter.im/ethereum/solidity) - - [Stack Overflow](https://ethereum.stackexchange.com/) + - [Solidity chat](https://gitter.im/ethereum/solidity) + - [Stack Overflow](https://ethereum.stackexchange.com/) - Ensure the issue isn't already reported (check `feature` and `language design` labels). *Delete the above section and the instructions in the sections below before submitting* - --> ## Abstract - + ## Motivation - + ## Specification - + ## Backwards Compatibility \ No newline at end of file +--> From 6035e8c02a96653fa659b667a3dd2ba7705b4967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 15 Dec 2021 21:07:08 +0100 Subject: [PATCH 0201/1748] Configure issue type selection screen to always select the "Solidity" project --- .github/ISSUE_TEMPLATE/config.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..931bc8940e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Bug Report + url: https://github.com/ethereum/solidity/issues/new?template=bug_report.md&projects=ethereum/solidity/43 + - name: Documentation Issue + url: https://github.com/ethereum/solidity/issues/new?template=documentation_issue.md&projects=ethereum/solidity/43 + - name: Feature Request + url: https://github.com/ethereum/solidity/issues/new?template=feature_request.md&projects=ethereum/solidity/43 From b2a05a1bcfafa4fbe1344eba19e6e63ceecb6d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 15 Dec 2021 21:07:28 +0100 Subject: [PATCH 0202/1748] Remove unused "general" issue template --- .github/ISSUE_TEMPLATE/general.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/general.md diff --git a/.github/ISSUE_TEMPLATE/general.md b/.github/ISSUE_TEMPLATE/general.md deleted file mode 100644 index e69de29bb2..0000000000 From 9a0821f2c30f9c51bb5d7e6ac4cc85cf42bd6c9b Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 16 Dec 2021 00:11:59 +0100 Subject: [PATCH 0203/1748] Fix warning about reference. --- libyul/backends/evm/StackLayoutGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index 43a1d032ce..50dcee5dec 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -247,7 +247,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla // before the operation, i.e. if PreviousSlot{2} is at a position at which _post contains VariableSlot{"tmp"}, // then we want the variable tmp in the slot at offset 2 in the layout before the operation. vector> idealLayout(_post.size(), nullopt); - for (auto const& [slot, idealPosition]: ranges::zip_view(_post, layout)) + for (auto&& [slot, idealPosition]: ranges::zip_view(_post, layout)) if (PreviousSlot* previousSlot = std::get_if(&idealPosition)) idealLayout.at(previousSlot->slot) = slot; From 19a74506e39af9448590ce4fefee65fdd7f9c8eb Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Wed, 17 Nov 2021 00:17:37 +0530 Subject: [PATCH 0204/1748] trial test cases extracted from SoliidityEndToEndTest.cpp into .sol files. removed libevmone.so files from the directory trial test cases extracted from SoliidityEndToEndTest.cpp into .sol files. Corresponding code in the .cpp file has been commented instead of begin removed pending preliminary reviews removed libevmone files Added testcase packed_storage_structs_delete added test case invalid_enum_logged added test case enum_referencing added test case memory_types_initialisation added test case return string added test case constant_string_literal.sol removed extractable keyword from solidityEndtoEnd.cpp, moved copying_bytes_multiassigned.sol to array/copying folder, added recv() function to copying_bytes_multiassigned.sol but this test case is failing now change typo error in the name of test case library_staticcall_delegatecal.sol to library_staticcall_delegatecall.sol Added compileToEwasm:false to call_forward_bytes.sol test case and moved it to semanticTests/fallback added compileToEwasm:false line to library_call_in_homestead added compileToEwasm: false line to copying_bytes_multiassign, copy_from_calldata_removes_bytes, enum_referencing, library_call_in_homestead, struct_referencing Added test case internal_types_in_library Added test case mapping_arguments_in_library Added test case mapping_returns_in_library Added test case mapping_returns_in_library_named Added test case using_library_mappings_public Added test case library_function_external Added test case library_stray_values added test case using_library_mappings_return added test case using_library_structs Added test case using_for_function_on_struct and corrections to using_library_structs, using_library_mpapings_return, library_stray_values Added test case using_for_overload added test case using_for_by_name added test case bound_function_in_function added test case bound_function_in_var added test case bound_function_to_string added test case payable_function_calls_library added function call corrections to copying_bytes_multiassign and call_forward_bytes Made changes to the test cases as per comments on PR #12289 mentioned in Changelog.md : Extraced some test cases from SolEndToEnd.cpp --- test/libsolidity/SolidityEndToEndTest.cpp | 519 ------------------ .../copying/copying_bytes_multiassign.sol | 33 ++ .../copy_from_calldata_removes_bytes_data.sol | 19 + .../semanticTests/enums/enum_referencing.sol | 41 ++ .../fallback/call_forward_bytes.sol | 27 + .../bound_function_in_function.sol | 16 + .../functionCall/bound_function_in_var.sol | 16 + .../functionCall/bound_function_to_string.sol | 20 + .../libraries/internal_types_in_library.sol | 30 + .../libraries/library_call_in_homestead.sol | 15 + .../libraries/library_stray_values.sol | 14 + .../mapping_arguments_in_library.sol | 41 ++ .../libraries/mapping_returns_in_library.sol | 75 +++ .../mapping_returns_in_library_named.sol | 31 ++ .../payable_function_calls_library.sol | 14 + .../libraries/using_for_by_name.sol | 16 + .../libraries/using_for_overload.sol | 20 + .../using_library_mappings_public.sol | 27 + .../using_library_mappings_return.sol | 25 + .../libraries/using_library_structs.sol | 27 + .../structs/struct_referencing.sol | 61 ++ .../structs/using_for_function_on_struct.sol | 16 + 22 files changed, 584 insertions(+), 519 deletions(-) create mode 100644 test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol create mode 100644 test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol create mode 100644 test/libsolidity/semanticTests/enums/enum_referencing.sol create mode 100644 test/libsolidity/semanticTests/fallback/call_forward_bytes.sol create mode 100644 test/libsolidity/semanticTests/functionCall/bound_function_in_function.sol create mode 100644 test/libsolidity/semanticTests/functionCall/bound_function_in_var.sol create mode 100644 test/libsolidity/semanticTests/functionCall/bound_function_to_string.sol create mode 100644 test/libsolidity/semanticTests/libraries/internal_types_in_library.sol create mode 100644 test/libsolidity/semanticTests/libraries/library_call_in_homestead.sol create mode 100644 test/libsolidity/semanticTests/libraries/library_stray_values.sol create mode 100644 test/libsolidity/semanticTests/libraries/mapping_arguments_in_library.sol create mode 100644 test/libsolidity/semanticTests/libraries/mapping_returns_in_library.sol create mode 100644 test/libsolidity/semanticTests/libraries/mapping_returns_in_library_named.sol create mode 100644 test/libsolidity/semanticTests/libraries/payable_function_calls_library.sol create mode 100644 test/libsolidity/semanticTests/libraries/using_for_by_name.sol create mode 100644 test/libsolidity/semanticTests/libraries/using_for_overload.sol create mode 100644 test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol create mode 100644 test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol create mode 100644 test/libsolidity/semanticTests/libraries/using_library_structs.sol create mode 100644 test/libsolidity/semanticTests/structs/struct_referencing.sol create mode 100644 test/libsolidity/semanticTests/structs/using_for_function_on_struct.sol diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 4731149618..314d4283e0 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1551,26 +1551,6 @@ BOOST_AUTO_TEST_CASE(generic_staticcall) } } -BOOST_AUTO_TEST_CASE(library_call_in_homestead) -{ - char const* sourceCode = R"( - library Lib { function m() public returns (address) { return msg.sender; } } - contract Test { - address public sender; - function f() public { - sender = Lib.m(); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs()); - ABI_CHECK(callContractFunction("sender()"), encodeArgs(m_sender)); - ) -} - BOOST_AUTO_TEST_CASE(library_call_protection) { // This tests code that reverts a call if it is a direct call to a library @@ -1626,38 +1606,6 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory) ); } -BOOST_AUTO_TEST_CASE(call_forward_bytes) -{ - char const* sourceCode = R"( - contract receiver { - uint public received; - function recv(uint x) public { received += x + 1; } - fallback() external { received = 0x80; } - } - contract sender { - constructor() { rec = new receiver(); } - fallback() external { savedData = msg.data; } - function forward() public returns (bool) { address(rec).call(savedData); return true; } - function clear() public returns (bool) { delete savedData; return true; } - function val() public returns (uint) { return rec.received(); } - receiver rec; - bytes savedData; - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN(); - compileAndRun(sourceCode, 0, "sender"); - ABI_CHECK(callContractFunction("recv(uint256)", 7), bytes()); - ABI_CHECK(callContractFunction("val()"), encodeArgs(0)); - ABI_CHECK(callContractFunction("forward()"), encodeArgs(true)); - ABI_CHECK(callContractFunction("val()"), encodeArgs(8)); - ABI_CHECK(callContractFunction("clear()"), encodeArgs(true)); - ABI_CHECK(callContractFunction("val()"), encodeArgs(8)); - ABI_CHECK(callContractFunction("forward()"), encodeArgs(true)); - ABI_CHECK(callContractFunction("val()"), encodeArgs(0x80)); - ); -} - BOOST_AUTO_TEST_CASE(call_forward_bytes_length) { char const* sourceCode = R"( @@ -2576,254 +2524,6 @@ BOOST_AUTO_TEST_CASE(library_function_external) ) } -BOOST_AUTO_TEST_CASE(library_stray_values) -{ - char const* sourceCode = R"( - library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } } - contract Test { - function f(uint x) public returns (uint) { - Lib; - Lib.m; - return x + 9; - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); - ABI_CHECK(callContractFunction("f(uint256)", u256(33)), encodeArgs(u256(42))); - ) -} - -BOOST_AUTO_TEST_CASE(internal_types_in_library) -{ - char const* sourceCode = R"( - library Lib { - function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint) - { - for (uint i = 0; i < _haystack.length; ++i) - if (_haystack[i] == _needle) - return i; - return type(uint).max; - } - } - contract Test { - mapping(string => uint16[]) data; - function f() public returns (uint a, uint b) - { - while (data["abc"].length < 20) - data["abc"].push(); - data["abc"][4] = 9; - data["abc"][17] = 3; - a = Lib.find(data["abc"], 9); - b = Lib.find(data["abc"], 3); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(4), u256(17))); - ) -} - -BOOST_AUTO_TEST_CASE(mapping_arguments_in_library) -{ - char const* sourceCode = R"( - library Lib { - function set(mapping(uint => uint) storage m, uint key, uint value) internal - { - m[key] = value; - } - function get(mapping(uint => uint) storage m, uint key) internal view returns (uint) - { - return m[key]; - } - } - contract Test { - mapping(uint => uint) m; - function set(uint256 key, uint256 value) public returns (uint) - { - uint oldValue = Lib.get(m, key); - Lib.set(m, key, value); - return oldValue; - } - function get(uint256 key) public view returns (uint) { - return Lib.get(m, key); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); - ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(1), u256(42)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(2), u256(84)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(21), u256(7)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get(uint256)", u256(0)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get(uint256)", u256(1)), encodeArgs(u256(42))); - ABI_CHECK(callContractFunction("get(uint256)", u256(2)), encodeArgs(u256(84))); - ABI_CHECK(callContractFunction("get(uint256)", u256(21)), encodeArgs(u256(7))); - ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(1), u256(21)), encodeArgs(u256(42))); - ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(2), u256(42)), encodeArgs(u256(84))); - ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(21), u256(14)), encodeArgs(u256(7))); - ABI_CHECK(callContractFunction("get(uint256)", u256(0)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get(uint256)", u256(1)), encodeArgs(u256(21))); - ABI_CHECK(callContractFunction("get(uint256)", u256(2)), encodeArgs(u256(42))); - ABI_CHECK(callContractFunction("get(uint256)", u256(21)), encodeArgs(u256(14))); - ) -} - -BOOST_AUTO_TEST_CASE(mapping_returns_in_library) -{ - char const* sourceCode = R"( - library Lib { - function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage) - { - return c ? a : b; - } - } - contract Test { - mapping(uint => uint) a; - mapping(uint => uint) b; - function set(bool choice, uint256 key, uint256 value) public returns (uint) - { - mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice); - uint oldValue = m[key]; - m[key] = value; - return oldValue; - } - function get(bool choice, uint256 key) public view returns (uint) { - return Lib.choose_mapping(a, b, choice)[key]; - } - function get_a(uint256 key) public view returns (uint) { - return a[key]; - } - function get_b(uint256 key) public view returns (uint) { - return b[key]; - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(1), u256(42)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(2), u256(84)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(21), u256(7)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(1), u256(10)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(2), u256(11)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(21), u256(12)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(0)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(1)), encodeArgs(u256(42))); - ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(2)), encodeArgs(u256(84))); - ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(21)), encodeArgs(u256(7))); - ABI_CHECK(callContractFunction("get_a(uint256)", u256(0)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get_a(uint256)", u256(1)), encodeArgs(u256(42))); - ABI_CHECK(callContractFunction("get_a(uint256)", u256(2)), encodeArgs(u256(84))); - ABI_CHECK(callContractFunction("get_a(uint256)", u256(21)), encodeArgs(u256(7))); - ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(0)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(1)), encodeArgs(u256(10))); - ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(2)), encodeArgs(u256(11))); - ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(21)), encodeArgs(u256(12))); - ABI_CHECK(callContractFunction("get_b(uint256)", u256(0)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get_b(uint256)", u256(1)), encodeArgs(u256(10))); - ABI_CHECK(callContractFunction("get_b(uint256)", u256(2)), encodeArgs(u256(11))); - ABI_CHECK(callContractFunction("get_b(uint256)", u256(21)), encodeArgs(u256(12))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(1), u256(21)), encodeArgs(u256(42))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(2), u256(42)), encodeArgs(u256(84))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(21), u256(14)), encodeArgs(u256(7))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(1), u256(30)), encodeArgs(u256(10))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(2), u256(31)), encodeArgs(u256(11))); - ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", false, u256(21), u256(32)), encodeArgs(u256(12))); - ABI_CHECK(callContractFunction("get_a(uint256)", u256(0)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get_a(uint256)", u256(1)), encodeArgs(u256(21))); - ABI_CHECK(callContractFunction("get_a(uint256)", u256(2)), encodeArgs(u256(42))); - ABI_CHECK(callContractFunction("get_a(uint256)", u256(21)), encodeArgs(u256(14))); - ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(0)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(1)), encodeArgs(u256(21))); - ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(2)), encodeArgs(u256(42))); - ABI_CHECK(callContractFunction("get(bool,uint256)", true, u256(21)), encodeArgs(u256(14))); - ABI_CHECK(callContractFunction("get_b(uint256)", u256(0)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get_b(uint256)", u256(1)), encodeArgs(u256(30))); - ABI_CHECK(callContractFunction("get_b(uint256)", u256(2)), encodeArgs(u256(31))); - ABI_CHECK(callContractFunction("get_b(uint256)", u256(21)), encodeArgs(u256(32))); - ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(0)), encodeArgs(u256(0))); - ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(1)), encodeArgs(u256(30))); - ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(2)), encodeArgs(u256(31))); - ABI_CHECK(callContractFunction("get(bool,uint256)", false, u256(21)), encodeArgs(u256(32))); - ) -} - -BOOST_AUTO_TEST_CASE(mapping_returns_in_library_named) -{ - char const* sourceCode = R"( - library Lib { - function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b) internal returns(mapping(uint=>uint) storage r) - { - r = a; - r[1] = 42; - r = b; - r[1] = 21; - } - } - contract Test { - mapping(uint => uint) a; - mapping(uint => uint) b; - function f() public returns (uint, uint, uint, uint, uint, uint) - { - Lib.f(a, b)[2] = 84; - return (a[0], a[1], a[2], b[0], b[1], b[2]); - } - function g() public returns (uint, uint, uint, uint, uint, uint) - { - mapping(uint => uint) storage m = Lib.f(a, b); - m[2] = 17; - return (a[0], a[1], a[2], b[0], b[1], b[2]); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0), u256(42), u256(0), u256(0), u256(21), u256(84))); - ABI_CHECK(callContractFunction("g()"), encodeArgs(u256(0), u256(42), u256(0), u256(0), u256(21), u256(17))); - ) -} - -BOOST_AUTO_TEST_CASE(using_library_mappings_public) -{ - char const* sourceCode = R"( - library Lib { - function set(mapping(uint => uint) storage m, uint key, uint value) public - { - m[key] = value; - } - } - contract Test { - mapping(uint => uint) m1; - mapping(uint => uint) m2; - function f() public returns (uint, uint, uint, uint, uint, uint) - { - Lib.set(m1, 0, 1); - Lib.set(m1, 2, 42); - Lib.set(m2, 0, 23); - Lib.set(m2, 2, 99); - return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1), u256(0), u256(42), u256(23), u256(0), u256(99))); - ) -} - BOOST_AUTO_TEST_CASE(using_library_mappings_external) { char const* libSourceCode = R"( @@ -2860,65 +2560,6 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_external) } } -BOOST_AUTO_TEST_CASE(using_library_mappings_return) -{ - char const* sourceCode = R"( - library Lib { - function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) { - return m[key]; - } - } - contract Test { - mapping(uint => mapping(uint => uint)) m; - function f() public returns (uint, uint, uint, uint, uint, uint) - { - Lib.choose(m, 0)[0] = 1; - Lib.choose(m, 0)[2] = 42; - Lib.choose(m, 1)[0] = 23; - Lib.choose(m, 1)[2] = 99; - return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1), u256(0), u256(42), u256(23), u256(0), u256(99))); - ) -} - -BOOST_AUTO_TEST_CASE(using_library_structs) -{ - char const* sourceCode = R"( - library Lib { - struct Data { uint a; uint[] b; } - function set(Data storage _s) public - { - _s.a = 7; - while (_s.b.length < 20) - _s.b.push(); - _s.b[19] = 8; - } - } - contract Test { - mapping(string => Lib.Data) data; - function f() public returns (uint a, uint b) - { - Lib.set(data["abc"]); - a = data["abc"].a; - b = data["abc"].b[19]; - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7), u256(8))); - ) -} - BOOST_AUTO_TEST_CASE(short_strings) { // This test verifies that the byte array encoding that combines length and data works @@ -3114,146 +2755,6 @@ BOOST_AUTO_TEST_CASE(create_memory_array_allocation_size) } } -BOOST_AUTO_TEST_CASE(using_for_function_on_struct) -{ - char const* sourceCode = R"( - library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } } - contract C { - using D for D.s; - D.s public x; - function f(uint a) public returns (uint) { - x.a = 3; - return x.mul(a); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); - ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(3 * 7))); - ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(3 * 7))); - ) -} - -BOOST_AUTO_TEST_CASE(using_for_overload) -{ - char const* sourceCode = R"( - library D { - struct s { uint a; } - function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } - function mul(s storage self, bytes32 x) public returns (bytes32) { } - } - contract C { - using D for D.s; - D.s public x; - function f(uint a) public returns (uint) { - x.a = 6; - return x.mul(a); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); - ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7))); - ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7))); - ) -} - -BOOST_AUTO_TEST_CASE(using_for_by_name) -{ - char const* sourceCode = R"( - library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } } - contract C { - using D for D.s; - D.s public x; - function f(uint a) public returns (uint) { - x.a = 6; - return x.mul({x: a}); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); - ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7))); - ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7))); - ) -} - -BOOST_AUTO_TEST_CASE(bound_function_in_function) -{ - char const* sourceCode = R"( - library L { - function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); } - } - contract C { - using L for *; - function f() public returns (uint) { - return t.g(); - } - function t() public pure returns (uint) { return 7; } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "L"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{":L", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7))); - ) -} - -BOOST_AUTO_TEST_CASE(bound_function_in_var) -{ - char const* sourceCode = R"( - library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } } - contract C { - using D for D.s; - D.s public x; - function f(uint a) public returns (uint) { - x.a = 6; - return (x.mul)({x: a}); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); - ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7))); - ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7))); - ) -} - -BOOST_AUTO_TEST_CASE(bound_function_to_string) -{ - char const* sourceCode = R"( - library D { function length(string memory self) public returns (uint) { return bytes(self).length; } } - contract C { - using D for string; - string x; - function f() public returns (uint) { - x = "abc"; - return x.length(); - } - function g() public returns (uint) { - string memory s = "abc"; - return s.length(); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(3))); - ABI_CHECK(callContractFunction("g()"), encodeArgs(u256(3))); - ) -} - BOOST_AUTO_TEST_CASE(inline_long_string_return) { char const* sourceCode = R"( @@ -3406,26 +2907,6 @@ BOOST_AUTO_TEST_CASE(payable_function) BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 27 + 27); } -BOOST_AUTO_TEST_CASE(payable_function_calls_library) -{ - char const* sourceCode = R"( - library L { - function f() public returns (uint) { return 7; } - } - contract C { - function f() public payable returns (uint) { - return L.f(); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode, 0, "L"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{":L", m_contractAddress}}); - ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs(u256(7))); - ) -} - BOOST_AUTO_TEST_CASE(non_payable_throw) { char const* sourceCode = R"( diff --git a/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol b/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol new file mode 100644 index 0000000000..3583a752d1 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol @@ -0,0 +1,33 @@ +contract receiver { + uint public received; + function recv(uint x) public { received += x + 1; } + fallback() external { received = 0x80; } +} +contract sender { + constructor() { rec = new receiver(); } + fallback() external { savedData1 = savedData2 = msg.data; } + function forward(bool selector) public returns (bool) { + if (selector) { address(rec).call(savedData1); delete savedData1; } + else { address(rec).call(savedData2); delete savedData2; } + return true; + } + function val() public returns (uint) { return rec.received(); } + receiver rec; + bytes savedData1; + bytes savedData2; +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// (): 7 -> +// gas irOptimized: 110941 +// gas legacy: 111082 +// gas legacyOptimized: 111027 +// val() -> 0 +// forward(bool): true -> true +// val() -> 0x80 +// forward(bool): false -> true +// val() -> 0x80 +// forward(bool): true -> true +// val() -> 0x80 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 new file mode 100644 index 0000000000..87067b77bc --- /dev/null +++ b/test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol @@ -0,0 +1,19 @@ +contract c { + function set() public returns (bool) { data = msg.data; return true; } + function checkIfDataIsEmpty() public returns (bool) { return data.length == 0; } + function sendMessage() public returns (bool, bytes memory) { bytes memory emptyData; return address(this).call(emptyData);} + fallback() external { data = msg.data; } + bytes data; +} +// ==== +// EVMVersion: >=byzantium +// compileToEwasm: false +// compileViaYul: also +// ---- +// (): 1, 2, 3, 4, 5 -> +// gas irOptimized: 155178 +// gas legacy: 155254 +// gas legacyOptimized: 155217 +// checkIfDataIsEmpty() -> false +// sendMessage() -> true, 0x40, 0 +// checkIfDataIsEmpty() -> true diff --git a/test/libsolidity/semanticTests/enums/enum_referencing.sol b/test/libsolidity/semanticTests/enums/enum_referencing.sol new file mode 100644 index 0000000000..537c05182b --- /dev/null +++ b/test/libsolidity/semanticTests/enums/enum_referencing.sol @@ -0,0 +1,41 @@ +interface I { + enum Direction { A, B, Left, Right } +} +library L { + enum Direction { Left, Right } + function f() public pure returns (Direction) { + return Direction.Right; + } + function g() public pure returns (I.Direction) { + return I.Direction.Right; + } +} +contract C is I { + function f() public pure returns (Direction) { + return Direction.Right; + } + function g() public pure returns (I.Direction) { + return I.Direction.Right; + } + function h() public pure returns (L.Direction) { + return L.Direction.Right; + } + function x() public pure returns (L.Direction) { + return L.f(); + } + function y() public pure returns (I.Direction) { + return L.g(); + } +} +// ==== +// compileViaYul: also +// compileToEwasm: false +// ---- +// library: L +// f() -> 3 +// g() -> 3 +// f() -> 3 +// g() -> 3 +// h() -> 1 +// x() -> 1 +// y() -> 3 diff --git a/test/libsolidity/semanticTests/fallback/call_forward_bytes.sol b/test/libsolidity/semanticTests/fallback/call_forward_bytes.sol new file mode 100644 index 0000000000..39122e7574 --- /dev/null +++ b/test/libsolidity/semanticTests/fallback/call_forward_bytes.sol @@ -0,0 +1,27 @@ +contract receiver { + uint256 public received; + function recv(uint256 x) public { received += x + 1; } + fallback() external { received = 0x80; } +} +contract sender { + constructor() { rec = new receiver();} + fallback() external { savedData = msg.data; } + function forward() public returns (bool) { address(rec).call(savedData); return true; } + function clear() public returns (bool) { delete savedData; return true; } + function val() public returns (uint) { return rec.received(); } + receiver rec; + bytes savedData; +} +// ==== +// allowNonExistingFunctions: true +// compileToEwasm: false +// compileViaYul: also +// ---- +// recv(uint256): 7 -> +// val() -> 0 +// forward() -> true +// val() -> 8 +// clear() -> true +// val() -> 8 +// forward() -> true +// val() -> 0x80 diff --git a/test/libsolidity/semanticTests/functionCall/bound_function_in_function.sol b/test/libsolidity/semanticTests/functionCall/bound_function_in_function.sol new file mode 100644 index 0000000000..983de5e3ce --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/bound_function_in_function.sol @@ -0,0 +1,16 @@ +library L { + function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); } +} +contract C { + using L for *; + function f() public returns (uint) { + return t.g(); + } + function t() public pure returns (uint) { return 7; } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: L +// f() -> 7 diff --git a/test/libsolidity/semanticTests/functionCall/bound_function_in_var.sol b/test/libsolidity/semanticTests/functionCall/bound_function_in_var.sol new file mode 100644 index 0000000000..ad80241270 --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/bound_function_in_var.sol @@ -0,0 +1,16 @@ +library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } } +contract C { + using D for D.s; + D.s public x; + function f(uint a) public returns (uint) { + x.a = 6; + return (x.mul)({x: a}); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: D +// f(uint256): 7 -> 0x2a +// x() -> 0x2a diff --git a/test/libsolidity/semanticTests/functionCall/bound_function_to_string.sol b/test/libsolidity/semanticTests/functionCall/bound_function_to_string.sol new file mode 100644 index 0000000000..376768b86d --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/bound_function_to_string.sol @@ -0,0 +1,20 @@ +library D { function length(string memory self) public returns (uint) { return bytes(self).length; } } +contract C { + using D for string; + string x; + function f() public returns (uint) { + x = "abc"; + return x.length(); + } + function g() public returns (uint) { + string memory s = "abc"; + return s.length(); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: D +// f() -> 3 +// g() -> 3 diff --git a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol new file mode 100644 index 0000000000..6b13ee09c3 --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol @@ -0,0 +1,30 @@ +library Lib { + function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint) + { + for (uint i = 0; i < _haystack.length; ++i) + if (_haystack[i] == _needle) + return i; + return type(uint).max; + } +} +contract Test { + mapping(string => uint16[]) data; + function f() public returns (uint a, uint b) + { + while (data["abc"].length < 20) + data["abc"].push(); + data["abc"][4] = 9; + data["abc"][17] = 3; + a = Lib.find(data["abc"], 9); + b = Lib.find(data["abc"], 3); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: Lib +// f() -> 4, 0x11 +// gas irOptimized: 115822 +// gas legacy: 135952 +// gas legacyOptimized: 119643 diff --git a/test/libsolidity/semanticTests/libraries/library_call_in_homestead.sol b/test/libsolidity/semanticTests/libraries/library_call_in_homestead.sol new file mode 100644 index 0000000000..6841221f41 --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/library_call_in_homestead.sol @@ -0,0 +1,15 @@ +library Lib { function m() public returns (address) { return msg.sender; } } +contract Test { + address public sender; + function f() public { + sender = Lib.m(); + } +} +// ==== +// compileViaYul: also +// compileToEwasm: false +// EVMVersion: >=homestead +// ---- +// library: Lib +// f() -> +// sender() -> 0x1212121212121212121212121212120000000012 diff --git a/test/libsolidity/semanticTests/libraries/library_stray_values.sol b/test/libsolidity/semanticTests/libraries/library_stray_values.sol new file mode 100644 index 0000000000..1692b018a7 --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/library_stray_values.sol @@ -0,0 +1,14 @@ +library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } } +contract Test { + function f(uint x) public returns (uint) { + Lib; + Lib.m; + return x + 9; + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: Lib +// f(uint256): 33 -> 0x2a diff --git a/test/libsolidity/semanticTests/libraries/mapping_arguments_in_library.sol b/test/libsolidity/semanticTests/libraries/mapping_arguments_in_library.sol new file mode 100644 index 0000000000..06cfd6e1a1 --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/mapping_arguments_in_library.sol @@ -0,0 +1,41 @@ +library Lib { + function set(mapping(uint => uint) storage m, uint key, uint value) internal + { + m[key] = value; + } + function get(mapping(uint => uint) storage m, uint key) internal view returns (uint) + { + return m[key]; + } +} +contract Test { + mapping(uint => uint) m; + function set(uint256 key, uint256 value) public returns (uint) + { + uint oldValue = Lib.get(m, key); + Lib.set(m, key, value); + return oldValue; + } + function get(uint256 key) public view returns (uint) { + return Lib.get(m, key); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: Lib +// set(uint256,uint256): 1, 42 -> 0 +// set(uint256,uint256): 2, 84 -> 0 +// set(uint256,uint256): 21, 7 -> 0 +// get(uint256): 0 -> 0 +// get(uint256): 1 -> 0x2a +// get(uint256): 2 -> 0x54 +// get(uint256): 21 -> 7 +// set(uint256,uint256): 1, 21 -> 0x2a +// set(uint256,uint256): 2, 42 -> 0x54 +// set(uint256,uint256): 21, 14 -> 7 +// get(uint256): 0 -> 0 +// get(uint256): 1 -> 0x15 +// get(uint256): 2 -> 0x2a +// get(uint256): 21 -> 14 diff --git a/test/libsolidity/semanticTests/libraries/mapping_returns_in_library.sol b/test/libsolidity/semanticTests/libraries/mapping_returns_in_library.sol new file mode 100644 index 0000000000..dd2b2953fa --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/mapping_returns_in_library.sol @@ -0,0 +1,75 @@ +library Lib { + function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage) + { + return c ? a : b; + } +} +contract Test { + mapping(uint => uint) a; + mapping(uint => uint) b; + function set(bool choice, uint256 key, uint256 value) public returns (uint) + { + mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice); + uint oldValue = m[key]; + m[key] = value; + return oldValue; + } + function get(bool choice, uint256 key) public view returns (uint) { + return Lib.choose_mapping(a, b, choice)[key]; + } + function get_a(uint256 key) public view returns (uint) { + return a[key]; + } + function get_b(uint256 key) public view returns (uint) { + return b[key]; + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: Lib +// set(bool,uint256,uint256): true, 1, 42 -> 0 +// set(bool,uint256,uint256): true, 2, 84 -> 0 +// set(bool,uint256,uint256): true, 21, 7 -> 0 +// set(bool,uint256,uint256): false, 1, 10 -> 0 +// set(bool,uint256,uint256): false, 2, 11 -> 0 +// set(bool,uint256,uint256): false, 21, 12 -> 0 +// get(bool,uint256): true, 0 -> 0 +// get(bool,uint256): true, 1 -> 0x2a +// get(bool,uint256): true, 2 -> 0x54 +// get(bool,uint256): true, 21 -> 7 +// get_a(uint256): 0 -> 0 +// get_a(uint256): 1 -> 0x2a +// get_a(uint256): 2 -> 0x54 +// get_a(uint256): 21 -> 7 +// get(bool,uint256): false, 0 -> 0 +// get(bool,uint256): false, 1 -> 10 +// get(bool,uint256): false, 2 -> 11 +// get(bool,uint256): false, 21 -> 12 +// get_b(uint256): 0 -> 0 +// get_b(uint256): 1 -> 10 +// get_b(uint256): 2 -> 11 +// get_b(uint256): 21 -> 12 +// set(bool,uint256,uint256): true, 1, 21 -> 0x2a +// set(bool,uint256,uint256): true, 2, 42 -> 0x54 +// set(bool,uint256,uint256): true, 21, 14 -> 7 +// set(bool,uint256,uint256): false, 1, 30 -> 10 +// set(bool,uint256,uint256): false, 2, 31 -> 11 +// set(bool,uint256,uint256): false, 21, 32 -> 12 +// get_a(uint256): 0 -> 0 +// get_a(uint256): 1 -> 0x15 +// get_a(uint256): 2 -> 0x2a +// get_a(uint256): 21 -> 14 +// get(bool,uint256): true, 0 -> 0 +// get(bool,uint256): true, 1 -> 0x15 +// get(bool,uint256): true, 2 -> 0x2a +// get(bool,uint256): true, 21 -> 14 +// get_b(uint256): 0 -> 0 +// get_b(uint256): 1 -> 0x1e +// get_b(uint256): 2 -> 0x1f +// get_b(uint256): 21 -> 0x20 +// get(bool,uint256): false, 0 -> 0 +// get(bool,uint256): false, 1 -> 0x1e +// get(bool,uint256): false, 2 -> 0x1f +// get(bool,uint256): false, 21 -> 0x20 diff --git a/test/libsolidity/semanticTests/libraries/mapping_returns_in_library_named.sol b/test/libsolidity/semanticTests/libraries/mapping_returns_in_library_named.sol new file mode 100644 index 0000000000..23f851279a --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/mapping_returns_in_library_named.sol @@ -0,0 +1,31 @@ +library Lib { + function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b) internal returns(mapping(uint=>uint) storage r) + { + r = a; + r[1] = 42; + r = b; + r[1] = 21; + } +} +contract Test { + mapping(uint => uint) a; + mapping(uint => uint) b; + function f() public returns (uint, uint, uint, uint, uint, uint) + { + Lib.f(a, b)[2] = 84; + return (a[0], a[1], a[2], b[0], b[1], b[2]); + } + function g() public returns (uint, uint, uint, uint, uint, uint) + { + mapping(uint => uint) storage m = Lib.f(a, b); + m[2] = 17; + return (a[0], a[1], a[2], b[0], b[1], b[2]); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: Lib +// f() -> 0, 0x2a, 0, 0, 0x15, 0x54 +// g() -> 0, 0x2a, 0, 0, 0x15, 0x11 diff --git a/test/libsolidity/semanticTests/libraries/payable_function_calls_library.sol b/test/libsolidity/semanticTests/libraries/payable_function_calls_library.sol new file mode 100644 index 0000000000..6b0488f06f --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/payable_function_calls_library.sol @@ -0,0 +1,14 @@ +library L { + function f() public returns (uint) { return 7; } +} +contract C { + function f() public payable returns (uint) { + return L.f(); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: L +// f(): 27 -> 7 diff --git a/test/libsolidity/semanticTests/libraries/using_for_by_name.sol b/test/libsolidity/semanticTests/libraries/using_for_by_name.sol new file mode 100644 index 0000000000..8a84c8aaac --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/using_for_by_name.sol @@ -0,0 +1,16 @@ +library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } } +contract C { + using D for D.s; + D.s public x; + function f(uint a) public returns (uint) { + x.a = 6; + return x.mul({x: a}); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: D +// f(uint256): 7 -> 0x2a +// x() -> 0x2a diff --git a/test/libsolidity/semanticTests/libraries/using_for_overload.sol b/test/libsolidity/semanticTests/libraries/using_for_overload.sol new file mode 100644 index 0000000000..54cfe0ce10 --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/using_for_overload.sol @@ -0,0 +1,20 @@ +library D { + struct s { uint a; } + function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } + function mul(s storage self, bytes32 x) public returns (bytes32) { } +} +contract C { + using D for D.s; + D.s public x; + function f(uint a) public returns (uint) { + x.a = 6; + return x.mul(a); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: D +// f(uint256): 7 -> 0x2a +// x() -> 0x2a diff --git a/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol b/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol new file mode 100644 index 0000000000..d85f906949 --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol @@ -0,0 +1,27 @@ +library Lib { + function set(mapping(uint => uint) storage m, uint key, uint value) public + { + m[key] = value; + } +} +contract Test { + mapping(uint => uint) m1; + mapping(uint => uint) m2; + function f() public returns (uint, uint, uint, uint, uint, uint) + { + Lib.set(m1, 0, 1); + Lib.set(m1, 2, 42); + Lib.set(m2, 0, 23); + Lib.set(m2, 2, 99); + return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: Lib +// f() -> 1, 0, 0x2a, 0x17, 0, 0x63 +// gas irOptimized: 119757 +// gas legacy: 124793 +// gas legacyOptimized: 119694 diff --git a/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol b/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol new file mode 100644 index 0000000000..9192fdfe31 --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol @@ -0,0 +1,25 @@ +library Lib { + function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) { + return m[key]; + } +} +contract Test { + mapping(uint => mapping(uint => uint)) m; + function f() public returns (uint, uint, uint, uint, uint, uint) + { + Lib.choose(m, 0)[0] = 1; + Lib.choose(m, 0)[2] = 42; + Lib.choose(m, 1)[0] = 23; + Lib.choose(m, 1)[2] = 99; + return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: Lib +// f() -> 1, 0, 0x2a, 0x17, 0, 0x63 +// gas irOptimized: 120471 +// gas legacy: 125245 +// gas legacyOptimized: 120153 diff --git a/test/libsolidity/semanticTests/libraries/using_library_structs.sol b/test/libsolidity/semanticTests/libraries/using_library_structs.sol new file mode 100644 index 0000000000..4348c377c7 --- /dev/null +++ b/test/libsolidity/semanticTests/libraries/using_library_structs.sol @@ -0,0 +1,27 @@ +library Lib { + struct Data { uint a; uint[] b; } + function set(Data storage _s) public + { + _s.a = 7; + while (_s.b.length < 20) + _s.b.push(); + _s.b[19] = 8; + } +} +contract Test { + mapping(string => Lib.Data) data; + function f() public returns (uint a, uint b) + { + Lib.set(data["abc"]); + a = data["abc"].a; + b = data["abc"].b[19]; + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: Lib +// f() -> 7, 8 +// gas irOptimized: 101869 +// gas legacy: 101504 diff --git a/test/libsolidity/semanticTests/structs/struct_referencing.sol b/test/libsolidity/semanticTests/structs/struct_referencing.sol new file mode 100644 index 0000000000..af2357a23e --- /dev/null +++ b/test/libsolidity/semanticTests/structs/struct_referencing.sol @@ -0,0 +1,61 @@ +pragma abicoder v2; +interface I { + struct S { uint a; } +} + +library L { + struct S { uint b; uint a; } + function f() public pure returns (S memory) { + S memory s; + s.a = 3; + return s; + } + function g() public pure returns (I.S memory) { + I.S memory s; + s.a = 4; + return s; + } + // argument-dependant lookup tests + function a(I.S memory) public pure returns (uint) { return 1; } + function a(S memory) public pure returns (uint) { return 2; } +} + +contract C is I { + function f() public pure returns (S memory) { + S memory s; + s.a = 1; + return s; + } + function g() public pure returns (I.S memory) { + I.S memory s; + s.a = 2; + return s; + } + function h() public pure returns (L.S memory) { + L.S memory s; + s.a = 5; + return s; + } + function x() public pure returns (L.S memory) { + return L.f(); + } + function y() public pure returns (I.S memory) { + return L.g(); + } + function a1() public pure returns (uint) { S memory s; return L.a(s); } + function a2() public pure returns (uint) { L.S memory s; return L.a(s); } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: L +// f() -> 1 +// g() -> 2 +// f() -> 1 +// g() -> 2 +// h() -> 0, 5 +// x() -> 0, 3 +// y() -> 4 +// a1() -> 1 +// a2() -> 2 diff --git a/test/libsolidity/semanticTests/structs/using_for_function_on_struct.sol b/test/libsolidity/semanticTests/structs/using_for_function_on_struct.sol new file mode 100644 index 0000000000..347aeb5951 --- /dev/null +++ b/test/libsolidity/semanticTests/structs/using_for_function_on_struct.sol @@ -0,0 +1,16 @@ +library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } } +contract C { + using D for D.s; + D.s public x; + function f(uint a) public returns (uint) { + x.a = 3; + return x.mul(a); + } +} +// ==== +// compileToEwasm: false +// compileViaYul: also +// ---- +// library: D +// f(uint256): 7 -> 0x15 +// x() -> 0x15 From 7cc7a0f1839c95607c8e2eb4a80bb5a8d82229fd Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Mon, 6 Dec 2021 18:01:27 +0530 Subject: [PATCH 0205/1748] Added sameType check for fromType and toType in YulUtilFunctions.cpp and relevant tests in semanticTests --- ...on_external_storage_to_storage_dynamic.sol | 46 +++++++++++------- ...o_storage_dynamic_different_mutability.sol | 48 ++++++++++++------- 2 files changed, 58 insertions(+), 36 deletions(-) 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 543342dfde..8bd9ee42c2 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 @@ -4,12 +4,27 @@ contract C { function testFunction3() public {} - function() external [3] externalArray0; - function() external [3] externalArray1 = [ - this.testFunction1, - this.testFunction2, - this.testFunction3 - ]; + function() external [] externalArray0; + function() external [] externalArray1; + + function() internal [] internalArray0; + function() internal [] internalArray1; + + constructor() { + externalArray0 = new function() external[] (3); + externalArray1 = [ + this.testFunction1, + this.testFunction2, + this.testFunction3 + ]; + + internalArray0 = new function() internal[] (3); + internalArray1 = [ + testFunction1, + testFunction2, + testFunction3 + ]; + } function copyExternalStorageArrayOfFunctionType() external returns (bool) { assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1))); @@ -17,27 +32,22 @@ contract C { return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1)); } - function() internal [3] internalArray0; - function() internal [3] internalArray1 = [ - testFunction1, - testFunction2, - testFunction3 - ]; - function copyInternalArrayOfFunctionType() external returns (bool) { internalArray0 = internalArray1; assert(internalArray0.length == 3); return - internalArray0.length == internalArray1.length && - internalArray0[0] == internalArray1[0] && - internalArray0[1] == internalArray1[1] && - internalArray0[2] == internalArray1[2]; + internalArray0.length == internalArray1.length && + internalArray0[0] == internalArray1[0] && + internalArray0[1] == internalArray1[1] && + internalArray0[2] == internalArray1[2]; } } // ==== // compileViaYul: also // ---- // copyExternalStorageArrayOfFunctionType() -> true -// gas legacy: 103412 +// gas irOptimized: 104701 +// gas legacy: 108725 +// gas legacyOptimized: 102441 // 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 0e356bce65..63236ed774 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 @@ -3,12 +3,29 @@ contract C { function testFunction2() public view {} function testFunction3() public pure {} - function() external [3] externalArray0; - function() external [3] externalArray1 = [ - this.testFunction1, - this.testFunction2, - this.testFunction3 - ]; + + function() external [] externalArray0; + function() external [] externalArray1; + + function() internal [] internalArray0; + function() internal [] internalArray1; + + constructor() { + externalArray0 = new function() external[] (3); + externalArray1 = [ + this.testFunction1, + this.testFunction2, + this.testFunction3 + ]; + + internalArray0 = new function() internal[] (3); + internalArray1 = [ + testFunction1, + testFunction2, + testFunction3 + ]; + } + function copyExternalStorageArraysOfFunctionType() external returns (bool) { @@ -17,29 +34,24 @@ contract C { return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1)); } - function() internal [3] internalArray0; - function() internal [3] internalArray1 = [ - testFunction1, - testFunction2, - testFunction3 - ]; - function copyInternalArrayOfFunctionType() external returns (bool) { internalArray0 = internalArray1; assert(internalArray0.length == 3); return - internalArray0.length == internalArray1.length && - internalArray0[0] == internalArray1[0] && - internalArray0[1] == internalArray1[1] && - internalArray0[2] == internalArray1[2]; + internalArray0.length == internalArray1.length && + internalArray0[0] == internalArray1[0] && + internalArray0[1] == internalArray1[1] && + internalArray0[2] == internalArray1[2]; } } // ==== // compileViaYul: also // ---- // copyExternalStorageArraysOfFunctionType() -> true -// gas legacy: 103398 +// gas irOptimized: 104372 +// gas legacy: 108462 +// gas legacyOptimized: 102174 // copyInternalArrayOfFunctionType() -> true // gas legacy: 104178 From 7a96953e78cc2083db182db1628ad68da785d03c Mon Sep 17 00:00:00 2001 From: Marenz Date: Thu, 11 Nov 2021 16:21:23 +0100 Subject: [PATCH 0206/1748] Implement typechecked abi.encodeCall() --- Changelog.md | 1 + docs/cheatsheet.rst | 2 + docs/units-and-global-variables.rst | 1 + libsolidity/analysis/TypeChecker.cpp | 113 ++++++++++++++++++ libsolidity/analysis/TypeChecker.h | 3 + libsolidity/analysis/ViewPureChecker.cpp | 1 + libsolidity/ast/Types.cpp | 11 ++ libsolidity/ast/Types.h | 1 + libsolidity/codegen/ExpressionCompiler.cpp | 56 ++++++--- .../codegen/ir/IRGeneratorForStatements.cpp | 48 ++++++-- libsolidity/formal/SMTEncoder.cpp | 2 + libsolidity/formal/SymbolicState.cpp | 9 ++ .../abiencodedecode/abi_encode_call.sol | 51 ++++++++ .../abi_encode_call_is_consistent.sol | 63 ++++++++++ .../abi_encode_call_memory.sol | 28 +++++ .../abi_encode_call_special_args.sol | 48 ++++++++ .../abi_encode_with_signaturev2.sol | 1 - .../abi/abi_encode_call_simple.sol | 26 ++++ .../specialFunctions/encodeCall.sol | 82 +++++++++++++ .../encodeCall_nested_tuple.sol | 9 ++ .../encodeCall_tuple_incomplete.sol | 8 ++ 21 files changed, 538 insertions(+), 26 deletions(-) create mode 100644 test/libsolidity/semanticTests/abiencodedecode/abi_encode_call.sol create mode 100644 test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_is_consistent.sol create mode 100644 test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_memory.sol create mode 100644 test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_special_args.sol create mode 100644 test/libsolidity/smtCheckerTests/abi/abi_encode_call_simple.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/encodeCall.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/encodeCall_nested_tuple.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/encodeCall_tuple_incomplete.sol diff --git a/Changelog.md b/Changelog.md index c4b67e935b..577bc40643 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.8.11 (unreleased) Language Features: + * General: New builtin function ``abi.encodeCall(functionPointer, (arg1, arg2, ...))`` that type-checks the arguments and returns the ABI-encoded function call data. Compiler Features: diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index 17537914ac..1aa8f24ef3 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -80,6 +80,8 @@ Global Variables the given arguments. Note that this encoding can be ambiguous! - ``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, (...))`` - ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)`` - ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatenates variable number of diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index ac11e08067..70125636c2 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -136,6 +136,7 @@ ABI Encoding and Decoding Functions - ``abi.encodePacked(...) returns (bytes memory)``: Performs :ref:`packed encoding ` of the given arguments. Note that packed encoding can be ambiguous! - ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: ABI-encodes the given arguments starting from the second and prepends the given four-byte selector - ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`` +- ``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, (...))`` .. note:: These encoding functions can be used to craft data for external function calls without actually diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 5cc208d698..aacd233a2a 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1996,6 +1996,7 @@ void TypeChecker::typeCheckABIEncodeFunctions( _functionType->kind() == FunctionType::Kind::ABIEncode || _functionType->kind() == FunctionType::Kind::ABIEncodePacked || _functionType->kind() == FunctionType::Kind::ABIEncodeWithSelector || + _functionType->kind() == FunctionType::Kind::ABIEncodeCall || _functionType->kind() == FunctionType::Kind::ABIEncodeWithSignature, "ABI function has unexpected FunctionType::Kind." ); @@ -2020,6 +2021,13 @@ void TypeChecker::typeCheckABIEncodeFunctions( // Perform standard function call type checking typeCheckFunctionGeneralChecks(_functionCall, _functionType); + // No further generic checks needed as we do a precise check for ABIEncodeCall + if (_functionType->kind() == FunctionType::Kind::ABIEncodeCall) + { + typeCheckABIEncodeCallFunction(_functionCall); + return; + } + // Check additional arguments for variadic functions vector> const& arguments = _functionCall.arguments(); for (size_t i = 0; i < arguments.size(); ++i) @@ -2078,6 +2086,110 @@ void TypeChecker::typeCheckABIEncodeFunctions( } } +void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCall) +{ + vector> const& arguments = _functionCall.arguments(); + + // Expecting first argument to be the function pointer and second to be a tuple. + if (arguments.size() != 2) + { + m_errorReporter.typeError( + 6219_error, + _functionCall.location(), + "Expected two arguments: a function pointer followed by a tuple." + ); + return; + } + + auto const functionPointerType = dynamic_cast(type(*arguments.front())); + + if (!functionPointerType) + { + m_errorReporter.typeError( + 5511_error, + arguments.front()->location(), + "Expected first argument to be a function pointer, not \"" + + type(*arguments.front())->canonicalName() + + "\"." + ); + return; + } + + if (functionPointerType->kind() != FunctionType::Kind::External) + { + string msg = "Function must be \"public\" or \"external\"."; + SecondarySourceLocation ssl{}; + + if (functionPointerType->hasDeclaration()) + { + ssl.append("Function is declared here:", functionPointerType->declaration().location()); + if (functionPointerType->declaration().scope() == m_currentContract) + msg += " Did you forget to prefix \"this.\"?"; + } + + m_errorReporter.typeError(3509_error, arguments[0]->location(), ssl, msg); + return; + } + + solAssert(!functionPointerType->takesArbitraryParameters(), "Function must have fixed parameters."); + + // Tuples with only one component become that component + vector> callArguments; + + auto const* tupleType = dynamic_cast(type(*arguments[1])); + if (tupleType) + { + auto const& argumentTuple = dynamic_cast(*arguments[1].get()); + callArguments = decltype(callArguments){argumentTuple.components().begin(), argumentTuple.components().end()}; + } + else + callArguments.push_back(arguments[1]); + + if (functionPointerType->parameterTypes().size() != callArguments.size()) + { + if (tupleType) + m_errorReporter.typeError( + 7788_error, + _functionCall.location(), + "Expected " + + to_string(functionPointerType->parameterTypes().size()) + + " instead of " + + to_string(callArguments.size()) + + " components for the tuple parameter." + ); + else + m_errorReporter.typeError( + 7515_error, + _functionCall.location(), + "Expected a tuple with " + + to_string(functionPointerType->parameterTypes().size()) + + " components instead of a single non-tuple parameter." + ); + } + + // Use min() to check as much as we can before failing fatally + size_t const numParameters = min(callArguments.size(), functionPointerType->parameterTypes().size()); + + for (size_t i = 0; i < numParameters; i++) + { + Type const& argType = *type(*callArguments[i]); + BoolResult result = argType.isImplicitlyConvertibleTo(*functionPointerType->parameterTypes()[i]); + if (!result) + m_errorReporter.typeError( + 5407_error, + callArguments[i]->location(), + "Cannot implicitly convert component at position " + + to_string(i) + + " from \"" + + argType.canonicalName() + + "\" to \"" + + functionPointerType->parameterTypes()[i]->canonicalName() + + "\"" + + (result.message().empty() ? "." : ": " + result.message()) + ); + } +} + void TypeChecker::typeCheckBytesConcatFunction( FunctionCall const& _functionCall, FunctionType const* _functionType @@ -2507,6 +2619,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) case FunctionType::Kind::ABIEncodePacked: case FunctionType::Kind::ABIEncodeWithSelector: case FunctionType::Kind::ABIEncodeWithSignature: + case FunctionType::Kind::ABIEncodeCall: { typeCheckABIEncodeFunctions(_functionCall, functionType); returnTypes = functionType->returnParameterTypes(); diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index ba445ffbb0..7586f9d151 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -110,6 +110,9 @@ class TypeChecker: private ASTConstVisitor FunctionTypePointer _functionType ); + /// Performs checks specific to the ABI encode functions of type ABIEncodeCall + void typeCheckABIEncodeCallFunction(FunctionCall const& _functionCall); + /// Performs general checks and checks specific to bytes concat function call void typeCheckBytesConcatFunction( FunctionCall const& _functionCall, diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 81f755cec0..252210a129 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -367,6 +367,7 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess) {MagicType::Kind::ABI, "encode"}, {MagicType::Kind::ABI, "encodePacked"}, {MagicType::Kind::ABI, "encodeWithSelector"}, + {MagicType::Kind::ABI, "encodeCall"}, {MagicType::Kind::ABI, "encodeWithSignature"}, {MagicType::Kind::Message, "data"}, {MagicType::Kind::Message, "sig"}, diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index fe0ac8ef86..aa1d5820f0 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2935,6 +2935,7 @@ string FunctionType::richIdentifier() const case Kind::ABIEncode: id += "abiencode"; break; case Kind::ABIEncodePacked: id += "abiencodepacked"; break; case Kind::ABIEncodeWithSelector: id += "abiencodewithselector"; break; + case Kind::ABIEncodeCall: id += "abiencodecall"; break; case Kind::ABIEncodeWithSignature: id += "abiencodewithsignature"; break; case Kind::ABIDecode: id += "abidecode"; break; case Kind::MetaType: id += "metatype"; break; @@ -3499,6 +3500,7 @@ bool FunctionType::isPure() const m_kind == Kind::ABIEncode || m_kind == Kind::ABIEncodePacked || m_kind == Kind::ABIEncodeWithSelector || + m_kind == Kind::ABIEncodeCall || m_kind == Kind::ABIEncodeWithSignature || m_kind == Kind::ABIDecode || m_kind == Kind::MetaType || @@ -4001,6 +4003,15 @@ MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const true, StateMutability::Pure )}, + {"encodeCall", TypeProvider::function( + TypePointers{}, + TypePointers{TypeProvider::array(DataLocation::Memory)}, + strings{}, + strings{1, ""}, + FunctionType::Kind::ABIEncodeCall, + true, + StateMutability::Pure + )}, {"encodeWithSignature", TypeProvider::function( TypePointers{TypeProvider::array(DataLocation::Memory, true)}, TypePointers{TypeProvider::array(DataLocation::Memory)}, diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index b08694820b..8b3826ca06 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -1237,6 +1237,7 @@ class FunctionType: public Type ABIEncode, ABIEncodePacked, ABIEncodeWithSelector, + ABIEncodeCall, ABIEncodeWithSignature, ABIDecode, GasLeft, ///< gasleft() diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 07d37c4c58..5a633d2e66 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1236,28 +1236,47 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) case FunctionType::Kind::ABIEncode: case FunctionType::Kind::ABIEncodePacked: case FunctionType::Kind::ABIEncodeWithSelector: + case FunctionType::Kind::ABIEncodeCall: case FunctionType::Kind::ABIEncodeWithSignature: { bool const isPacked = function.kind() == FunctionType::Kind::ABIEncodePacked; bool const hasSelectorOrSignature = function.kind() == FunctionType::Kind::ABIEncodeWithSelector || + function.kind() == FunctionType::Kind::ABIEncodeCall || function.kind() == FunctionType::Kind::ABIEncodeWithSignature; TypePointers argumentTypes; - TypePointers targetTypes; - for (unsigned i = 0; i < arguments.size(); ++i) + + ASTNode::listAccept(arguments, *this); + + if (function.kind() == FunctionType::Kind::ABIEncodeCall) { - arguments[i]->accept(*this); - // Do not keep the selector as part of the ABI encoded args - if (!hasSelectorOrSignature || i > 0) - argumentTypes.push_back(arguments[i]->annotation().type); + solAssert(arguments.size() == 2); + + auto const functionPtr = dynamic_cast(arguments[0]->annotation().type); + solAssert(functionPtr); + solAssert(functionPtr->sizeOnStack() == 2); + + // Account for tuples with one component which become that component + if (auto const tupleType = dynamic_cast(arguments[1]->annotation().type)) + argumentTypes = tupleType->components(); + else + argumentTypes.emplace_back(arguments[1]->annotation().type); } + else + for (unsigned i = 0; i < arguments.size(); ++i) + { + // Do not keep the selector as part of the ABI encoded args + if (!hasSelectorOrSignature || i > 0) + argumentTypes.push_back(arguments[i]->annotation().type); + } + utils().fetchFreeMemoryPointer(); - // stack now: [] .. + // stack now: [] .. // adjust by 32(+4) bytes to accommodate the length(+selector) m_context << u256(32 + (hasSelectorOrSignature ? 4 : 0)) << Instruction::ADD; - // stack now: [] .. + // stack now: [] .. if (isPacked) { @@ -1270,7 +1289,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) utils().abiEncode(argumentTypes, TypePointers()); } utils().fetchFreeMemoryPointer(); - // stack: [] + // stack: [] // size is end minus start minus length slot m_context.appendInlineAssembly(R"({ @@ -1278,16 +1297,17 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) })", {"mem_end", "mem_ptr"}); m_context << Instruction::SWAP1; utils().storeFreeMemoryPointer(); - // stack: [] + // stack: [] if (hasSelectorOrSignature) { - // stack: + // stack: solAssert(arguments.size() >= 1, ""); Type const* selectorType = arguments[0]->annotation().type; utils().moveIntoStack(selectorType->sizeOnStack()); Type const* dataOnStack = selectorType; - // stack: + + // stack: if (function.kind() == FunctionType::Kind::ABIEncodeWithSignature) { // hash the signature @@ -1299,7 +1319,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) else { utils().fetchFreeMemoryPointer(); - // stack: + // stack: utils().packedEncode(TypePointers{selectorType}, TypePointers()); utils().toSizeAfterFreeMemoryPointer(); m_context << Instruction::KECCAK256; @@ -1308,10 +1328,16 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) dataOnStack = TypeProvider::fixedBytes(32); } } - else + else if (function.kind() == FunctionType::Kind::ABIEncodeCall) { - solAssert(function.kind() == FunctionType::Kind::ABIEncodeWithSelector, ""); + // stack: + // Extract selector from the stack + m_context << Instruction::SWAP1 << Instruction::POP; + // Conversion will be done below + dataOnStack = TypeProvider::uint(32); } + else + solAssert(function.kind() == FunctionType::Kind::ABIEncodeWithSelector, ""); utils().convertType(*dataOnStack, FixedBytesType(4), true); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 85b21bbdcd..179b3e739b 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1104,29 +1104,57 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) case FunctionType::Kind::ABIEncode: case FunctionType::Kind::ABIEncodePacked: case FunctionType::Kind::ABIEncodeWithSelector: + case FunctionType::Kind::ABIEncodeCall: case FunctionType::Kind::ABIEncodeWithSignature: { bool const isPacked = functionType->kind() == FunctionType::Kind::ABIEncodePacked; solAssert(functionType->padArguments() != isPacked, ""); bool const hasSelectorOrSignature = functionType->kind() == FunctionType::Kind::ABIEncodeWithSelector || + functionType->kind() == FunctionType::Kind::ABIEncodeCall || functionType->kind() == FunctionType::Kind::ABIEncodeWithSignature; TypePointers argumentTypes; TypePointers targetTypes; vector argumentVars; - for (size_t i = 0; i < arguments.size(); ++i) + string selector; + vector> argumentsOfEncodeFunction; + + if (functionType->kind() == FunctionType::Kind::ABIEncodeCall) { - // ignore selector - if (hasSelectorOrSignature && i == 0) - continue; - argumentTypes.emplace_back(&type(*arguments[i])); - targetTypes.emplace_back(type(*arguments[i]).fullEncodingType(false, true, isPacked)); - argumentVars += IRVariable(*arguments[i]).stackSlots(); + solAssert(arguments.size() == 2, ""); + // Account for tuples with one component which become that component + if (type(*arguments[1]).category() == Type::Category::Tuple) + { + auto const& tupleExpression = dynamic_cast(*arguments[1]); + for (auto component: tupleExpression.components()) + argumentsOfEncodeFunction.push_back(component); + } + else + argumentsOfEncodeFunction.push_back(arguments[1]); } + else + for (size_t i = 0; i < arguments.size(); ++i) + { + // ignore selector + if (hasSelectorOrSignature && i == 0) + continue; + argumentsOfEncodeFunction.push_back(arguments[i]); + } - string selector; - if (functionType->kind() == FunctionType::Kind::ABIEncodeWithSignature) + for (auto const& argument: argumentsOfEncodeFunction) + { + argumentTypes.emplace_back(&type(*argument)); + targetTypes.emplace_back(type(*argument).fullEncodingType(false, true, isPacked)); + argumentVars += IRVariable(*argument).stackSlots(); + } + + if (functionType->kind() == FunctionType::Kind::ABIEncodeCall) + selector = convert( + IRVariable(*arguments[0]).part("functionSelector"), + *TypeProvider::fixedBytes(4) + ).name(); + else if (functionType->kind() == FunctionType::Kind::ABIEncodeWithSignature) { // hash the signature Type const& selectorType = type(*arguments.front()); @@ -1833,7 +1861,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) define(_memberAccess) << requestedValue << "\n"; } - else if (set{"encode", "encodePacked", "encodeWithSelector", "encodeWithSignature", "decode"}.count(member)) + else if (set{"encode", "encodePacked", "encodeWithSelector", "encodeCall", "encodeWithSignature", "decode"}.count(member)) { // no-op } diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 8326b6b2f8..68545f4f6b 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -637,6 +637,7 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall) case FunctionType::Kind::ABIEncode: case FunctionType::Kind::ABIEncodePacked: case FunctionType::Kind::ABIEncodeWithSelector: + case FunctionType::Kind::ABIEncodeCall: case FunctionType::Kind::ABIEncodeWithSignature: visitABIFunction(_funCall); break; @@ -3041,6 +3042,7 @@ set SMTEncoder::collectABICalls(ASTNode const* _node) case FunctionType::Kind::ABIEncode: case FunctionType::Kind::ABIEncodePacked: case FunctionType::Kind::ABIEncodeWithSelector: + case FunctionType::Kind::ABIEncodeCall: case FunctionType::Kind::ABIEncodeWithSignature: case FunctionType::Kind::ABIDecode: abiCalls.insert(&_funCall); diff --git a/libsolidity/formal/SymbolicState.cpp b/libsolidity/formal/SymbolicState.cpp index e136f347db..6612723d06 100644 --- a/libsolidity/formal/SymbolicState.cpp +++ b/libsolidity/formal/SymbolicState.cpp @@ -236,6 +236,15 @@ void SymbolicState::buildABIFunctions(set const& _abiFuncti else solAssert(false, "Unexpected argument of abi.decode"); } + else if (t->kind() == FunctionType::Kind::ABIEncodeCall) + { + // abi.encodeCall : (functionPointer, tuple_of_args_or_one_non_tuple_arg(arguments)) -> bytes + solAssert(args.size() == 2, "Unexpected number of arguments for abi.encodeCall"); + + outTypes.emplace_back(TypeProvider::bytesMemory()); + inTypes.emplace_back(args.at(0)->annotation().type); + inTypes.emplace_back(args.at(1)->annotation().type); + } else { outTypes = returnTypes; diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call.sol new file mode 100644 index 0000000000..dc6ead60b2 --- /dev/null +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call.sol @@ -0,0 +1,51 @@ +pragma abicoder v2; +contract C { + type UnsignedNumber is uint256; + enum Enum { First, Second, Third } + + struct Struct { + UnsignedNumber[] dynamicArray; + uint256 justAnInt; + string name; + bytes someBytes; + Enum theEnum; + } + + function callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure { + assert(_data.dynamicArray.length == 3); + assert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0); + assert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1); + assert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2); + assert(_data.justAnInt == 6); + assert(keccak256(bytes(_data.name)) == keccak256("StructName")); + assert(keccak256(_data.someBytes) == keccak256(bytes("1234"))); + assert(_data.theEnum == Enum.Second); + assert(_intVal == 5); + assert(keccak256(bytes(_nameVal)) == keccak256("TestName")); + } + + function callExternal() public returns (bool) { + Struct memory structToSend; + structToSend.dynamicArray = new UnsignedNumber[](3); + structToSend.dynamicArray[0] = UnsignedNumber.wrap(0); + structToSend.dynamicArray[1] = UnsignedNumber.wrap(1); + structToSend.dynamicArray[2] = UnsignedNumber.wrap(2); + structToSend.justAnInt = 6; + structToSend.name = "StructName"; + structToSend.someBytes = bytes("1234"); + structToSend.theEnum = Enum.Second; + + (bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, ( + structToSend, + 5, + "TestName" + ))); + + return success; + } +} + +// ==== +// compileViaYul: also +// ---- +// callExternal() -> true diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_is_consistent.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_is_consistent.sol new file mode 100644 index 0000000000..3c053e38a4 --- /dev/null +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_is_consistent.sol @@ -0,0 +1,63 @@ +pragma abicoder v2; + +contract C { + bool sideEffectRan = false; + + function(uint256, string memory) external fPointer; + function fExternal(uint256 p, string memory t) external {} + string xstor; + function getExternalFunctionPointer() public returns (function(uint256, string memory) external) { + sideEffectRan = true; + return this.fExternal; + } + + function fSignatureFromLiteral() public pure returns (bytes memory) { + return abi.encodeWithSignature("fExternal(uint256,string)", 1, "123"); + } + function fSignatureFromLiteralCall() public view returns (bytes memory) { + return abi.encodeCall(this.fExternal, (1, "123")); + } + function fSignatureFromMemory() public pure returns (bytes memory) { + string memory x = "fExternal(uint256,string)"; + return abi.encodeWithSignature(x, 1, "123"); + } + function fSignatureFromMemoryCall() public view returns (bytes memory) { + return abi.encodeCall(this.fExternal, (1,"123")); + } + function fSignatureFromMemorys() public returns (bytes memory) { + xstor = "fExternal(uint256,string)"; + return abi.encodeWithSignature(xstor, 1, "123"); + } + function fPointerCall() public returns(bytes memory) { + fPointer = this.fExternal; + return abi.encodeCall(fPointer, (1, "123")); + } + function fLocalPointerCall() public returns(bytes memory) { + function(uint256, string memory) external localFunctionPointer = this.fExternal; + return abi.encodeCall(localFunctionPointer, (1, "123")); + } + function fReturnedFunctionPointer() public returns (bytes memory) { + return abi.encodeCall(getExternalFunctionPointer(), (1, "123")); + } + + function assertConsistentSelectors() public { + assert(keccak256(fSignatureFromLiteral()) == keccak256(fSignatureFromLiteralCall())); + assert(keccak256(fSignatureFromMemory()) == keccak256(fSignatureFromMemoryCall())); + assert(keccak256(fSignatureFromMemoryCall()) == keccak256(fSignatureFromMemorys())); + assert(keccak256(fPointerCall()) == keccak256(fSignatureFromLiteral())); + assert(keccak256(fLocalPointerCall()) == keccak256(fSignatureFromLiteral())); + assert(keccak256(fReturnedFunctionPointer()) == keccak256(fSignatureFromLiteral())); + } +} +// ==== +// compileViaYul: also +// ---- +// assertConsistentSelectors() -> +// fSignatureFromLiteral() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fSignatureFromLiteralCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fSignatureFromMemory() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fSignatureFromMemoryCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fSignatureFromMemorys() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fLocalPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fReturnedFunctionPointer() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_memory.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_memory.sol new file mode 100644 index 0000000000..781a6684f4 --- /dev/null +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_memory.sol @@ -0,0 +1,28 @@ +pragma abicoder v2; + +contract D { + function something() external pure {} +} + +contract C { + function something() external pure {} + function test() external returns (bytes4) { + function() external[2] memory x; + x[0] = this.something; + x[1] = (new D()).something; + function() external f = x[1]; + bytes memory a = abi.encodeCall(x[0], ()); + bytes memory b = abi.encodeCall(x[1], ()); + bytes memory c = abi.encodeCall(f, ()); + assert(a.length == 4 && b.length == 4 && c.length == 4); + assert(bytes4(a) == bytes4(b)); + assert(bytes4(a) == bytes4(c)); + assert(bytes4(a) == f.selector); + return bytes4(a); + } +} + +// ==== +// compileViaYul: also +// ---- +// test() -> 0xa7a0d53700000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_special_args.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_special_args.sol new file mode 100644 index 0000000000..24e6d065f9 --- /dev/null +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_call_special_args.sol @@ -0,0 +1,48 @@ +pragma abicoder v2; + +contract C { + bool sideEffectRan = false; + + function fNoArgs() external {} + function fArray(uint[] memory x) external {} + function fUint(uint x, uint y) external returns (uint a, uint b) {} + + function fSignatureFromLiteralNoArgs() public pure returns (bytes memory) { + return abi.encodeWithSignature("fNoArgs()"); + } + function fPointerNoArgs() public view returns (bytes memory) { + return abi.encodeCall(this.fNoArgs, ()); + } + + function fSignatureFromLiteralArray() public pure returns (bytes memory) { + uint[] memory x; + return abi.encodeWithSignature("fArray(uint256[])", x); + } + function fPointerArray() public view returns (bytes memory) { + uint[] memory x; + return abi.encodeCall(this.fArray, x); + } + + function fSignatureFromLiteralUint() public pure returns (bytes memory) { + return abi.encodeWithSignature("fUint(uint256,uint256)", 12, 13); + } + function fPointerUint() public view returns (bytes memory) { + return abi.encodeCall(this.fUint, (12,13)); + } + + function assertConsistentSelectors() public view { + assert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs())); + assert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray())); + assert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint())); + } +} +// ==== +// compileViaYul: also +// ---- +// assertConsistentSelectors() -> +// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832 +// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832 +// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0 +// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0 +// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808 +// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808 diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signaturev2.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signaturev2.sol index f6333a9476..1968a76a83 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signaturev2.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_encode_with_signaturev2.sol @@ -26,7 +26,6 @@ contract C { } struct S { uint a; string b; uint16 c; } function f4() public pure returns (bytes memory) { - bytes4 x = 0x12345678; S memory s; s.a = 0x1234567; s.b = "Lorem ipsum dolor sit ethereum........"; diff --git a/test/libsolidity/smtCheckerTests/abi/abi_encode_call_simple.sol b/test/libsolidity/smtCheckerTests/abi/abi_encode_call_simple.sol new file mode 100644 index 0000000000..72fd4290c3 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/abi/abi_encode_call_simple.sol @@ -0,0 +1,26 @@ +contract C { + function callMeMaybe(uint a, uint b, uint[] memory c) external {} + + function abiEncodeSimple(uint x, uint y, uint z, uint[] memory a, uint[] memory b) public view { + require(x == y); + bytes memory b1 = abi.encodeCall(this.callMeMaybe, (x, z, a)); + bytes memory b2 = abi.encodeCall(this.callMeMaybe, (y, z, a)); + assert(b1.length == b2.length); + + bytes memory b3 = abi.encodeCall(this.callMeMaybe, (y, z, b)); + assert(b1.length == b3.length); // should fail + } +} +// ==== +// SMTEngine: all +// SMTIgnoreCex: yes +// ---- +// Warning 6031: (233-249): Internal error: Expression undefined for SMT solver. +// Warning 6031: (298-314): Internal error: Expression undefined for SMT solver. +// Warning 6031: (398-414): Internal error: Expression undefined for SMT solver. +// Warning 1218: (330-360): CHC: Error trying to invoke SMT solver. +// Warning 1218: (430-460): CHC: Error trying to invoke SMT solver. +// Warning 6328: (330-360): CHC: Assertion violation might happen here. +// Warning 6328: (430-460): CHC: Assertion violation might happen here. +// Warning 4661: (330-360): BMC: Assertion violation happens here. +// Warning 4661: (430-460): BMC: Assertion violation happens here. diff --git a/test/libsolidity/syntaxTests/specialFunctions/encodeCall.sol b/test/libsolidity/syntaxTests/specialFunctions/encodeCall.sol new file mode 100644 index 0000000000..41b8f16ccb --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/encodeCall.sol @@ -0,0 +1,82 @@ +interface I { + function fExternal(uint256 p, string memory t) external; +} + +library L { + function fExternal(uint256 p, string memory t) external {} +} + +contract C { + using L for uint256; + + function f(int a) public {} + function f2(int a, string memory b) public {} + function f3(int a, int b) public {} + function f4() public {} + function fInternal(uint256 p, string memory t) internal {} + + function failFunctionArgsWrongType() public returns(bytes memory) { + return abi.encodeCall(this.f, ("test")); + } + function failFunctionArgsTooMany() public returns(bytes memory) { + return abi.encodeCall(this.f, (1, 2)); + } + function failFunctionArgsTooFew0() public returns(bytes memory) { + return abi.encodeCall(this.f, ()); + } + function failFunctionArgsTooFew1() public returns(bytes memory) { + return abi.encodeCall(this.f); + } + function failFunctionPtrMissing() public returns(bytes memory) { + return abi.encodeCall(1, this.f); + } + function failFunctionPtrWrongType() public returns(bytes memory) { + return abi.encodeCall(abi.encodeCall, (1, 2, 3, "test")); + } + function failFunctionInternal() public returns(bytes memory) { + return abi.encodeCall(fInternal, (1, "123")); + } + function failFunctionInternalFromVariable() public returns(bytes memory) { + function(uint256, string memory) internal localFunctionPointer = fInternal; + return abi.encodeCall(localFunctionPointer, (1, "123")); + } + function failFunctionArgsArrayLiteral() public returns(bytes memory) { + return abi.encodeCall(this.f3, [1, 2]); + } + function failLibraryPointerCall() public returns (bytes memory) { + return abi.encodeCall(L.fExternal, (1, "123")); + } + function failBoundLibraryPointerCall() public returns (bytes memory) { + uint256 x = 1; + return abi.encodeCall(x.fExternal, (1, "123")); + } + function failInterfacePointerCall() public returns (bytes memory) { + return abi.encodeCall(I.fExternal, (1, "123")); + } + function successFunctionArgsIntLiteralTuple() public returns(bytes memory) { + return abi.encodeCall(this.f, (1)); + } + function successFunctionArgsIntLiteral() public returns(bytes memory) { + return abi.encodeCall(this.f, 1); + } + function successFunctionArgsLiteralTuple() public returns(bytes memory) { + return abi.encodeCall(this.f2, (1, "test")); + } + function successFunctionArgsEmptyTuple() public returns(bytes memory) { + return abi.encodeCall(this.f4, ()); + } +} +// ---- +// TypeError 5407: (486-494): Cannot implicitly convert component at position 0 from "literal_string "test"" to "int256". +// TypeError 7788: (576-606): Expected 1 instead of 2 components for the tuple parameter. +// TypeError 7788: (687-713): Expected 1 instead of 0 components for the tuple parameter. +// TypeError 6219: (794-816): Expected two arguments: a function pointer followed by a tuple. +// TypeError 5511: (911-912): Expected first argument to be a function pointer, not "int_const 1". +// TypeError 3509: (1018-1032): Function must be "public" or "external". +// TypeError 3509: (1145-1154): Function must be "public" or "external". Did you forget to prefix "this."? +// TypeError 3509: (1350-1370): Function must be "public" or "external". +// TypeError 7515: (1469-1500): Expected a tuple with 2 components instead of a single non-tuple parameter. +// TypeError 5407: (1493-1499): Cannot implicitly convert component at position 0 from "uint8[2]" to "int256". +// TypeError 3509: (1596-1607): Function must be "public" or "external". +// TypeError 3509: (1738-1749): Function must be "public" or "external". +// TypeError 3509: (1860-1871): Function must be "public" or "external". diff --git a/test/libsolidity/syntaxTests/specialFunctions/encodeCall_nested_tuple.sol b/test/libsolidity/syntaxTests/specialFunctions/encodeCall_nested_tuple.sol new file mode 100644 index 0000000000..c27f61d687 --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/encodeCall_nested_tuple.sol @@ -0,0 +1,9 @@ +contract C { + function f(int a, int b) public {} + function failFunctionArgsIntLiteralNestedTuple() public returns(bytes memory) { + return abi.encodeCall(this.f, ((1,2))); + } +} +// ---- +// TypeError 7788: (139-170): Expected 2 instead of 1 components for the tuple parameter. +// TypeError 5407: (163-168): Cannot implicitly convert component at position 0 from "tuple(int_const 1,int_const 2)" to "int256". diff --git a/test/libsolidity/syntaxTests/specialFunctions/encodeCall_tuple_incomplete.sol b/test/libsolidity/syntaxTests/specialFunctions/encodeCall_tuple_incomplete.sol new file mode 100644 index 0000000000..7f69995d5e --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/encodeCall_tuple_incomplete.sol @@ -0,0 +1,8 @@ +contract C { + function f(int a) public {} + function failFunctionArgsIntLiteralTuple() public returns(bytes memory) { + return abi.encodeCall(this.f, (1,)); + } +} +// ---- +// TypeError 8381: (149-153): Tuple component cannot be empty. From fc88226376b97a53f39a1c70956fe138f13a0a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 16 Dec 2021 17:47:43 +0100 Subject: [PATCH 0207/1748] Move `about` field from issue templates to `config.yml` --- .github/ISSUE_TEMPLATE/bug_report.md | 1 - .github/ISSUE_TEMPLATE/config.yml | 3 +++ .github/ISSUE_TEMPLATE/documentation_issue.md | 1 - .github/ISSUE_TEMPLATE/feature_request.md | 1 - 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 261f78fdc1..7be77f4226 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,5 @@ --- name: Bug Report -about: Bug reports about the Solidity Compiler. labels: ["bug :bug:"] --- diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 931bc8940e..139c117874 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,7 +2,10 @@ blank_issues_enabled: false contact_links: - name: Bug Report url: https://github.com/ethereum/solidity/issues/new?template=bug_report.md&projects=ethereum/solidity/43 + about: Bug reports about the Solidity Compiler. - name: Documentation Issue url: https://github.com/ethereum/solidity/issues/new?template=documentation_issue.md&projects=ethereum/solidity/43 + about: Solidity documentation. - name: Feature Request url: https://github.com/ethereum/solidity/issues/new?template=feature_request.md&projects=ethereum/solidity/43 + about: Solidity language or infrastructure feature requests. diff --git a/.github/ISSUE_TEMPLATE/documentation_issue.md b/.github/ISSUE_TEMPLATE/documentation_issue.md index c5873f726c..9e58b88684 100644 --- a/.github/ISSUE_TEMPLATE/documentation_issue.md +++ b/.github/ISSUE_TEMPLATE/documentation_issue.md @@ -1,6 +1,5 @@ --- name: Documentation Issue -about: Solidity documentation. labels: ["documentation :book:"] --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 7191414d43..0b5bfbd4af 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,6 +1,5 @@ --- name: Feature Request -about: Solidity language or infrastructure feature requests. labels: ["feature"] --- From 927b24df1f37cdffc794a74081cfb37d01d47c17 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Mon, 13 Dec 2021 14:53:40 +0100 Subject: [PATCH 0208/1748] Initial implementation of Language Server --- .circleci/config.yml | 20 +- Changelog.md | 1 + libsolidity/CMakeLists.txt | 6 + libsolidity/lsp/FileRepository.cpp | 64 ++ libsolidity/lsp/FileRepository.h | 53 ++ libsolidity/lsp/LanguageServer.cpp | 402 ++++++++ libsolidity/lsp/LanguageServer.h | 110 +++ libsolidity/lsp/Transport.cpp | 141 +++ libsolidity/lsp/Transport.h | 101 ++ scripts/tests.sh | 3 + solc/CommandLineInterface.cpp | 19 +- solc/CommandLineInterface.h | 1 + solc/CommandLineParser.cpp | 14 + solc/CommandLineParser.h | 1 + test/libsolidity/lsp/didChange_template.sol | 6 + test/libsolidity/lsp/didOpen_with_import.sol | 12 + test/libsolidity/lsp/lib.sol | 15 + .../libsolidity/lsp/publish_diagnostics_1.sol | 18 + .../libsolidity/lsp/publish_diagnostics_2.sol | 21 + .../libsolidity/lsp/publish_diagnostics_3.sol | 10 + test/lsp.py | 874 ++++++++++++++++++ test/solc/CommandLineInterface.cpp | 2 +- 22 files changed, 1891 insertions(+), 3 deletions(-) create mode 100644 libsolidity/lsp/FileRepository.cpp create mode 100644 libsolidity/lsp/FileRepository.h create mode 100644 libsolidity/lsp/LanguageServer.cpp create mode 100644 libsolidity/lsp/LanguageServer.h create mode 100644 libsolidity/lsp/Transport.cpp create mode 100644 libsolidity/lsp/Transport.h create mode 100644 test/libsolidity/lsp/didChange_template.sol create mode 100644 test/libsolidity/lsp/didOpen_with_import.sol create mode 100644 test/libsolidity/lsp/lib.sol create mode 100644 test/libsolidity/lsp/publish_diagnostics_1.sol create mode 100644 test/libsolidity/lsp/publish_diagnostics_2.sol create mode 100644 test/libsolidity/lsp/publish_diagnostics_3.sol create mode 100755 test/lsp.py diff --git a/.circleci/config.yml b/.circleci/config.yml index cda6e58909..8123fefe84 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -198,6 +198,19 @@ defaults: - store_artifacts: *artifacts_test_results - gitter_notify_failure_unless_pr + - steps_test_lsp: &steps_test_lsp + steps: + - 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 + - gitter_notify_failure_unless_pr + - steps_soltest_all: &steps_soltest_all steps: - checkout @@ -519,7 +532,7 @@ jobs: command: apt -q update && apt install -y python3-pip - run: name: Install pylint - command: python3 -m pip install pylint z3-solver pygments-lexer-solidity parsec tabulate + command: python3 -m pip install pylint z3-solver pygments-lexer-solidity parsec tabulate deepdiff colorama # also z3-solver, parsec and tabulate to make sure pylint knows about this module, pygments-lexer-solidity for docs - run: name: Linting Python Scripts @@ -887,6 +900,10 @@ jobs: parallelism: 15 # 7 EVM versions, each with/without optimization + 1 ABIv1/@nooptions run <<: *steps_soltest_all + t_ubu_lsp: &t_ubu_lsp + <<: *base_ubuntu2004_small + <<: *steps_test_lsp + t_archlinux_soltest: &t_archlinux_soltest <<: *base_archlinux environment: @@ -1288,6 +1305,7 @@ workflows: - t_ubu_soltest_enforce_yul: *workflow_ubuntu2004 - b_ubu_clang: *workflow_trigger_on_tags - t_ubu_clang_soltest: *workflow_ubuntu2004_clang + - t_ubu_lsp: *workflow_ubuntu2004 # Ubuntu fake release build and tests - b_ubu_release: *workflow_trigger_on_tags diff --git a/Changelog.md b/Changelog.md index c4b67e935b..9e3526fab8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Language Features: Compiler Features: + * Commandline Interface: Add ``--lsp`` option to get ``solc`` to act as a Language Server (LSP) communicating over stdio. Bugfixes: diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 7e3791eab0..ff82cd9fb5 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -155,6 +155,12 @@ set(sources interface/StorageLayout.h interface/Version.cpp interface/Version.h + lsp/LanguageServer.cpp + lsp/LanguageServer.h + lsp/FileRepository.cpp + lsp/FileRepository.h + lsp/Transport.cpp + lsp/Transport.h parsing/DocStringParser.cpp parsing/DocStringParser.h parsing/Parser.cpp diff --git a/libsolidity/lsp/FileRepository.cpp b/libsolidity/lsp/FileRepository.cpp new file mode 100644 index 0000000000..9c7f72e0c4 --- /dev/null +++ b/libsolidity/lsp/FileRepository.cpp @@ -0,0 +1,64 @@ +/* + 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 std; +using namespace solidity; +using namespace solidity::lsp; + +namespace +{ + +string stripFilePrefix(string const& _path) +{ + if (_path.find("file://") == 0) + return _path.substr(7); + else + return _path; +} + +} + +string FileRepository::sourceUnitNameToClientPath(string const& _sourceUnitName) const +{ + if (m_sourceUnitNamesToClientPaths.count(_sourceUnitName)) + return m_sourceUnitNamesToClientPaths.at(_sourceUnitName); + else if (_sourceUnitName.find("file://") == 0) + return _sourceUnitName; + else + return "file://" + (m_fileReader.basePath() / _sourceUnitName).generic_string(); +} + +string FileRepository::clientPathToSourceUnitName(string const& _path) const +{ + return m_fileReader.cliPathToSourceUnitName(stripFilePrefix(_path)); +} + +map const& FileRepository::sourceUnits() const +{ + return m_fileReader.sourceUnits(); +} + +void FileRepository::setSourceByClientPath(string const& _uri, string _text) +{ + // This is needed for uris outside the base path. It can lead to collisions, + // but we need to mostly rewrite this in a future version anyway. + m_sourceUnitNamesToClientPaths.emplace(clientPathToSourceUnitName(_uri), _uri); + m_fileReader.addOrUpdateFile(stripFilePrefix(_uri), move(_text)); +} diff --git a/libsolidity/lsp/FileRepository.h b/libsolidity/lsp/FileRepository.h new file mode 100644 index 0000000000..b6aa5ee085 --- /dev/null +++ b/libsolidity/lsp/FileRepository.h @@ -0,0 +1,53 @@ +/* + 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::lsp +{ + +class FileRepository +{ +public: + explicit FileRepository(boost::filesystem::path const& _basePath): + m_fileReader(_basePath) {} + + boost::filesystem::path const& basePath() const { return m_fileReader.basePath(); } + + /// Translates a compiler-internal source unit name to an LSP client path. + std::string sourceUnitNameToClientPath(std::string const& _sourceUnitName) const; + /// Translates an LSP client path into a compiler-internal source unit name. + std::string clientPathToSourceUnitName(std::string const& _uri) const; + + /// @returns all sources by their compiler-internal source unit name. + std::map const& sourceUnits() const; + /// Changes the source identified by the LSP client path _uri to _text. + void setSourceByClientPath(std::string const& _uri, std::string _text); + + frontend::ReadCallback::Callback reader() { return m_fileReader.reader(); } + +private: + std::map m_sourceUnitNamesToClientPaths; + frontend::FileReader m_fileReader; +}; + +} diff --git a/libsolidity/lsp/LanguageServer.cpp b/libsolidity/lsp/LanguageServer.cpp new file mode 100644 index 0000000000..586220df11 --- /dev/null +++ b/libsolidity/lsp/LanguageServer.cpp @@ -0,0 +1,402 @@ +/* + 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 +#include + +using namespace std; +using namespace std::placeholders; + +using namespace solidity::lsp; +using namespace solidity::langutil; +using namespace solidity::frontend; + +namespace +{ + +Json::Value toJson(LineColumn _pos) +{ + Json::Value json = Json::objectValue; + json["line"] = max(_pos.line, 0); + json["character"] = max(_pos.column, 0); + + return json; +} + +Json::Value toJsonRange(LineColumn const& _start, LineColumn const& _end) +{ + Json::Value json; + json["start"] = toJson(_start); + json["end"] = toJson(_end); + return json; +} + +optional parseLineColumn(Json::Value const& _lineColumn) +{ + if (_lineColumn.isObject() && _lineColumn["line"].isInt() && _lineColumn["character"].isInt()) + return LineColumn{_lineColumn["line"].asInt(), _lineColumn["character"].asInt()}; + else + return nullopt; +} + +constexpr int toDiagnosticSeverity(Error::Type _errorType) +{ + // 1=Error, 2=Warning, 3=Info, 4=Hint + switch (Error::errorSeverity(_errorType)) + { + case Error::Severity::Error: return 1; + case Error::Severity::Warning: return 2; + case Error::Severity::Info: return 3; + } + solAssert(false); + return -1; +} + +} + +LanguageServer::LanguageServer(Transport& _transport): + m_client{_transport}, + m_handlers{ + {"$/cancelRequest", [](auto, auto) {/*nothing for now as we are synchronous */}}, + {"cancelRequest", [](auto, auto) {/*nothing for now as we are synchronous */}}, + {"exit", [this](auto, auto) { m_state = (m_state == State::ShutdownRequested ? State::ExitRequested : State::ExitWithoutShutdown); }}, + {"initialize", bind(&LanguageServer::handleInitialize, this, _1, _2)}, + {"initialized", [](auto, auto) {}}, + {"shutdown", [this](auto, auto) { m_state = State::ShutdownRequested; }}, + {"textDocument/didOpen", bind(&LanguageServer::handleTextDocumentDidOpen, this, _1, _2)}, + {"textDocument/didChange", bind(&LanguageServer::handleTextDocumentDidChange, this, _1, _2)}, + {"textDocument/didClose", bind(&LanguageServer::handleTextDocumentDidClose, this, _1, _2)}, + {"workspace/didChangeConfiguration", bind(&LanguageServer::handleWorkspaceDidChangeConfiguration, this, _1, _2)}, + }, + m_fileRepository("/" /* basePath */), + m_compilerStack{m_fileRepository.reader()} +{ +} + +optional LanguageServer::parsePosition( + string const& _sourceUnitName, + Json::Value const& _position +) const +{ + if (!m_fileRepository.sourceUnits().count(_sourceUnitName)) + return nullopt; + + if (optional lineColumn = parseLineColumn(_position)) + if (optional const offset = CharStream::translateLineColumnToPosition( + m_fileRepository.sourceUnits().at(_sourceUnitName), + *lineColumn + )) + return SourceLocation{*offset, *offset, make_shared(_sourceUnitName)}; + return nullopt; +} + +optional LanguageServer::parseRange(string const& _sourceUnitName, Json::Value const& _range) const +{ + if (!_range.isObject()) + return nullopt; + optional start = parsePosition(_sourceUnitName, _range["start"]); + optional end = parsePosition(_sourceUnitName, _range["end"]); + if (!start || !end) + return nullopt; + solAssert(*start->sourceName == *end->sourceName); + start->end = end->end; + return start; +} + +Json::Value LanguageServer::toRange(SourceLocation const& _location) const +{ + if (!_location.hasText()) + return toJsonRange({}, {}); + + solAssert(_location.sourceName, ""); + CharStream const& stream = m_compilerStack.charStream(*_location.sourceName); + LineColumn start = stream.translatePositionToLineColumn(_location.start); + LineColumn end = stream.translatePositionToLineColumn(_location.end); + return toJsonRange(start, end); +} + +Json::Value LanguageServer::toJson(SourceLocation const& _location) const +{ + solAssert(_location.sourceName); + Json::Value item = Json::objectValue; + item["uri"] = m_fileRepository.sourceUnitNameToClientPath(*_location.sourceName); + item["range"] = toRange(_location); + return item; +} + +void LanguageServer::changeConfiguration(Json::Value const& _settings) +{ + m_settingsObject = _settings; +} + +void LanguageServer::compile() +{ + // For files that are not open, we have to take changes on disk into account, + // so we just remove all non-open files. + + FileRepository oldRepository(m_fileRepository.basePath()); + swap(oldRepository, m_fileRepository); + + for (string const& fileName: m_openFiles) + m_fileRepository.setSourceByClientPath( + fileName, + oldRepository.sourceUnits().at(oldRepository.clientPathToSourceUnitName(fileName)) + ); + + // TODO: optimize! do not recompile if nothing has changed (file(s) not flagged dirty). + + m_compilerStack.reset(false); + m_compilerStack.setSources(m_fileRepository.sourceUnits()); + m_compilerStack.compile(CompilerStack::State::AnalysisPerformed); +} + +void LanguageServer::compileAndUpdateDiagnostics() +{ + compile(); + + // These are the source units we will sent diagnostics to the client for sure, + // even if it is just to clear previous diagnostics. + map diagnosticsBySourceUnit; + for (string const& sourceUnitName: m_fileRepository.sourceUnits() | ranges::views::keys) + diagnosticsBySourceUnit[sourceUnitName] = Json::arrayValue; + for (string const& sourceUnitName: m_nonemptyDiagnostics) + diagnosticsBySourceUnit[sourceUnitName] = Json::arrayValue; + + for (shared_ptr const& error: m_compilerStack.errors()) + { + SourceLocation const* location = error->sourceLocation(); + if (!location || !location->sourceName) + // LSP only has diagnostics applied to individual files. + continue; + + Json::Value jsonDiag; + jsonDiag["source"] = "solc"; + jsonDiag["severity"] = toDiagnosticSeverity(error->type()); + jsonDiag["code"] = Json::UInt64{error->errorId().error}; + string message = error->typeName() + ":"; + if (string const* comment = error->comment()) + message += " " + *comment; + jsonDiag["message"] = move(message); + jsonDiag["range"] = toRange(*location); + + if (auto const* secondary = error->secondarySourceLocation()) + for (auto&& [secondaryMessage, secondaryLocation]: secondary->infos) + { + Json::Value jsonRelated; + jsonRelated["message"] = secondaryMessage; + jsonRelated["location"] = toJson(secondaryLocation); + jsonDiag["relatedInformation"].append(jsonRelated); + } + + diagnosticsBySourceUnit[*location->sourceName].append(jsonDiag); + } + + m_nonemptyDiagnostics.clear(); + for (auto&& [sourceUnitName, diagnostics]: diagnosticsBySourceUnit) + { + Json::Value params; + params["uri"] = m_fileRepository.sourceUnitNameToClientPath(sourceUnitName); + if (!diagnostics.empty()) + m_nonemptyDiagnostics.insert(sourceUnitName); + params["diagnostics"] = move(diagnostics); + m_client.notify("textDocument/publishDiagnostics", move(params)); + } +} + +bool LanguageServer::run() +{ + while (m_state != State::ExitRequested && m_state != State::ExitWithoutShutdown && !m_client.closed()) + { + MessageID id; + try + { + optional const jsonMessage = m_client.receive(); + if (!jsonMessage) + continue; + + if ((*jsonMessage)["method"].isString()) + { + string const methodName = (*jsonMessage)["method"].asString(); + id = (*jsonMessage)["id"]; + + if (auto handler = valueOrDefault(m_handlers, methodName)) + handler(id, (*jsonMessage)["params"]); + else + m_client.error(id, ErrorCode::MethodNotFound, "Unknown method " + methodName); + } + else + m_client.error({}, ErrorCode::ParseError, "\"method\" has to be a string."); + } + catch (...) + { + m_client.error(id, ErrorCode::InternalError, "Unhandled exception: "s + boost::current_exception_diagnostic_information()); + } + } + return m_state == State::ExitRequested; +} + +bool LanguageServer::checkServerInitialized(MessageID _id) +{ + if (m_state != State::Initialized) + { + m_client.error(_id, ErrorCode::ServerNotInitialized, "Server is not properly initialized."); + return false; + } + else + return true; +} + +void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args) +{ + if (m_state != State::Started) + { + m_client.error(_id, ErrorCode::RequestFailed, "Initialize called at the wrong time."); + return; + } + m_state = State::Initialized; + + // The default of FileReader is to use `.`, but the path from where the LSP was started + // should not matter. + string rootPath("/"); + if (Json::Value uri = _args["rootUri"]) + { + rootPath = uri.asString(); + if (!boost::starts_with(rootPath, "file://")) + { + m_client.error(_id, ErrorCode::InvalidParams, "rootUri only supports file URI scheme."); + return; + } + rootPath = rootPath.substr(7); + } + else if (Json::Value rootPath = _args["rootPath"]) + rootPath = rootPath.asString(); + + m_fileRepository = FileRepository(boost::filesystem::path(rootPath)); + if (_args["initializationOptions"].isObject()) + changeConfiguration(_args["initializationOptions"]); + + Json::Value replyArgs; + replyArgs["serverInfo"]["name"] = "solc"; + replyArgs["serverInfo"]["version"] = string(VersionNumber); + replyArgs["capabilities"]["textDocumentSync"]["openClose"] = true; + replyArgs["capabilities"]["textDocumentSync"]["change"] = 2; // 0=none, 1=full, 2=incremental + + m_client.reply(_id, move(replyArgs)); +} + + +void LanguageServer::handleWorkspaceDidChangeConfiguration(MessageID _id, Json::Value const& _args) +{ + if (!checkServerInitialized(_id)) + return; + + if (_args["settings"].isObject()) + changeConfiguration(_args["settings"]); +} + +void LanguageServer::handleTextDocumentDidOpen(MessageID _id, Json::Value const& _args) +{ + if (!checkServerInitialized(_id)) + return; + + if (!_args["textDocument"]) + m_client.error(_id, ErrorCode::RequestFailed, "Text document parameter missing."); + + string text = _args["textDocument"]["text"].asString(); + string uri = _args["textDocument"]["uri"].asString(); + m_openFiles.insert(uri); + m_fileRepository.setSourceByClientPath(uri, move(text)); + compileAndUpdateDiagnostics(); +} + +void LanguageServer::handleTextDocumentDidChange(MessageID _id, Json::Value const& _args) +{ + if (!checkServerInitialized(_id)) + return; + + string const uri = _args["textDocument"]["uri"].asString(); + + for (Json::Value jsonContentChange: _args["contentChanges"]) + { + if (!jsonContentChange.isObject()) + { + m_client.error(_id, ErrorCode::RequestFailed, "Invalid content reference."); + return; + } + + string const sourceUnitName = m_fileRepository.clientPathToSourceUnitName(uri); + if (!m_fileRepository.sourceUnits().count(sourceUnitName)) + { + m_client.error(_id, ErrorCode::RequestFailed, "Unknown file: " + uri); + return; + } + + string text = jsonContentChange["text"].asString(); + if (jsonContentChange["range"].isObject()) // otherwise full content update + { + optional change = parseRange(sourceUnitName, jsonContentChange["range"]); + if (!change || !change->hasText()) + { + m_client.error( + _id, + ErrorCode::RequestFailed, + "Invalid source range: " + jsonCompactPrint(jsonContentChange["range"]) + ); + return; + } + string buffer = m_fileRepository.sourceUnits().at(sourceUnitName); + buffer.replace(static_cast(change->start), static_cast(change->end - change->start), move(text)); + text = move(buffer); + } + m_fileRepository.setSourceByClientPath(uri, move(text)); + } + + compileAndUpdateDiagnostics(); +} + +void LanguageServer::handleTextDocumentDidClose(MessageID _id, Json::Value const& _args) +{ + if (!checkServerInitialized(_id)) + return; + + if (!_args["textDocument"]) + m_client.error(_id, ErrorCode::RequestFailed, "Text document parameter missing."); + + string uri = _args["textDocument"]["uri"].asString(); + m_openFiles.erase(uri); + + compileAndUpdateDiagnostics(); +} diff --git a/libsolidity/lsp/LanguageServer.h b/libsolidity/lsp/LanguageServer.h new file mode 100644 index 0000000000..802dd81989 --- /dev/null +++ b/libsolidity/lsp/LanguageServer.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 +#include +#include +#include +#include + +namespace solidity::lsp +{ + +enum class ErrorCode; + +/** + * Solidity Language Server, managing one LSP client. + * This implements a subset of LSP version 3.16 that can be found at: + * https://microsoft.github.io/language-server-protocol/specifications/specification-3-16/ + */ +class LanguageServer +{ +public: + /// @param _transport Customizable transport layer. + explicit LanguageServer(Transport& _transport); + + /// Re-compiles the project and updates the diagnostics pushed to the client. + void compileAndUpdateDiagnostics(); + + /// Loops over incoming messages via the transport layer until shutdown condition is met. + /// + /// The standard shutdown condition is when the maximum number of consecutive failures + /// has been exceeded. + /// + /// @return boolean indicating normal or abnormal termination. + bool run(); + +private: + /// 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. + bool checkServerInitialized(MessageID _id); + void handleInitialize(MessageID _id, Json::Value const& _args); + void handleWorkspaceDidChangeConfiguration(MessageID _id, Json::Value const& _args); + void handleTextDocumentDidOpen(MessageID _id, Json::Value const& _args); + void handleTextDocumentDidChange(MessageID _id, Json::Value const& _args); + void handleTextDocumentDidClose(MessageID _id, Json::Value const& _args); + + /// Invoked when the server user-supplied configuration changes (initiated by the client). + void changeConfiguration(Json::Value const&); + + /// Compile everything until after analysis phase. + void compile(); + + std::optional parsePosition( + std::string const& _sourceUnitName, + Json::Value const& _position + ) const; + /// @returns the source location given a source unit name and an LSP Range object, + /// or nullopt on failure. + std::optional parseRange( + std::string const& _sourceUnitName, + Json::Value const& _range + ) const; + Json::Value toRange(langutil::SourceLocation const& _location) const; + Json::Value toJson(langutil::SourceLocation const& _location) const; + + // LSP related member fields + using MessageHandler = std::function; + + enum class State { Started, Initialized, ShutdownRequested, ExitRequested, ExitWithoutShutdown }; + State m_state = State::Started; + + Transport& m_client; + std::map m_handlers; + + /// Set of files known to be open by the client. + std::set m_openFiles; + /// Set of source unit names for which we sent diagnostics to the client in the last iteration. + std::set m_nonemptyDiagnostics; + FileRepository m_fileRepository; + + frontend::CompilerStack m_compilerStack; + + /// User-supplied custom configuration settings (such as EVM version). + Json::Value m_settingsObject; +}; + +} diff --git a/libsolidity/lsp/Transport.cpp b/libsolidity/lsp/Transport.cpp new file mode 100644 index 0000000000..fcd3c82492 --- /dev/null +++ b/libsolidity/lsp/Transport.cpp @@ -0,0 +1,141 @@ +/* + 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 + +using namespace std; +using namespace solidity::lsp; + +IOStreamTransport::IOStreamTransport(istream& _in, ostream& _out): + m_input{_in}, + m_output{_out} +{ +} + +IOStreamTransport::IOStreamTransport(): + IOStreamTransport(cin, cout) +{ +} + +bool IOStreamTransport::closed() const noexcept +{ + return m_input.eof(); +} + +optional IOStreamTransport::receive() +{ + auto const headers = parseHeaders(); + if (!headers) + { + error({}, ErrorCode::ParseError, "Could not parse RPC headers."); + return nullopt; + } + + if (!headers->count("content-length")) + { + error({}, ErrorCode::ParseError, "No content-length header found."); + return nullopt; + } + + string const data = util::readBytes(m_input, stoul(headers->at("content-length"))); + + Json::Value jsonMessage; + string jsonParsingErrors; + solidity::util::jsonParseStrict(data, jsonMessage, &jsonParsingErrors); + if (!jsonParsingErrors.empty() || !jsonMessage || !jsonMessage.isObject()) + { + error({}, ErrorCode::ParseError, "Could not parse RPC JSON payload. " + jsonParsingErrors); + return nullopt; + } + + return {move(jsonMessage)}; +} + +void IOStreamTransport::notify(string _method, Json::Value _message) +{ + Json::Value json; + json["method"] = move(_method); + json["params"] = move(_message); + send(move(json)); +} + +void IOStreamTransport::reply(MessageID _id, Json::Value _message) +{ + Json::Value json; + json["result"] = move(_message); + send(move(json), _id); +} + +void IOStreamTransport::error(MessageID _id, ErrorCode _code, string _message) +{ + Json::Value json; + json["error"]["code"] = static_cast(_code); + json["error"]["message"] = move(_message); + send(move(json), _id); +} + +void IOStreamTransport::send(Json::Value _json, MessageID _id) +{ + solAssert(_json.isObject()); + _json["jsonrpc"] = "2.0"; + if (_id != Json::nullValue) + _json["id"] = _id; + + string const jsonString = solidity::util::jsonCompactPrint(_json); + + m_output << "Content-Length: " << jsonString.size() << "\r\n"; + m_output << "\r\n"; + m_output << jsonString; + + m_output.flush(); +} + +optional> IOStreamTransport::parseHeaders() +{ + map headers; + + while (true) + { + string line; + getline(m_input, line); + if (boost::trim_copy(line).empty()) + break; + + auto const delimiterPos = line.find(':'); + if (delimiterPos == string::npos) + return nullopt; + + string name = boost::to_lower_copy(line.substr(0, delimiterPos)); + string value = line.substr(delimiterPos + 1); + if (!headers.emplace( + boost::trim_copy(name), + boost::trim_copy(value) + ).second) + return nullopt; + } + return {move(headers)}; +} diff --git a/libsolidity/lsp/Transport.h b/libsolidity/lsp/Transport.h new file mode 100644 index 0000000000..c6ed8fa8a2 --- /dev/null +++ b/libsolidity/lsp/Transport.h @@ -0,0 +1,101 @@ +/* + 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 + +namespace solidity::lsp +{ + +using MessageID = Json::Value; + +enum class ErrorCode +{ + // Defined by JSON RPC + ParseError = -32700, + MethodNotFound = -32601, + InvalidParams = -32602, + InternalError = -32603, + + // Defined by the protocol. + ServerNotInitialized = -32002, + RequestFailed = -32803 +}; + +/** + * Transport layer API + * + * The transport layer API is abstracted to make LSP more testable as well as + * this way it could be possible to support other transports (HTTP for example) easily. + */ +class Transport +{ +public: + virtual ~Transport() = default; + + virtual bool closed() const noexcept = 0; + virtual std::optional receive() = 0; + virtual void notify(std::string _method, Json::Value _params) = 0; + virtual void reply(MessageID _id, Json::Value _result) = 0; + virtual void error(MessageID _id, ErrorCode _code, std::string _message) = 0; +}; + +/** + * LSP Transport using JSON-RPC over iostreams. + */ +class IOStreamTransport: public Transport +{ +public: + /// Constructs a standard stream transport layer. + /// + /// @param _in for example std::cin (stdin) + /// @param _out for example std::cout (stdout) + IOStreamTransport(std::istream& _in, std::ostream& _out); + + // Constructs a JSON transport using standard I/O streams. + IOStreamTransport(); + + bool closed() const noexcept override; + std::optional receive() override; + void notify(std::string _method, Json::Value _params) override; + void reply(MessageID _id, Json::Value _result) override; + void error(MessageID _id, ErrorCode _code, std::string _message) override; + +protected: + /// 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); + + /// Parses header section from the client including message-delimiting empty line. + std::optional> parseHeaders(); + +private: + std::istream& m_input; + std::ostream& m_output; +}; + +} diff --git a/scripts/tests.sh b/scripts/tests.sh index 029be16291..5515a68691 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -83,6 +83,9 @@ done printTask "Testing Python scripts..." "$REPO_ROOT/test/pyscriptTests.py" +printTask "Testing LSP..." +"$REPO_ROOT/scripts/test_solidity_lsp.py" "${SOLIDITY_BUILD_DIR}/solc/solc" + printTask "Running commandline tests..." # Only run in parallel if this is run on CI infrastructure if [[ -n "$CI" ]] diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 94bfd8a68b..235059a02b 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include @@ -56,6 +58,7 @@ #include #include +#include #include #include @@ -499,7 +502,11 @@ void CommandLineInterface::readInputFiles() m_fileReader.setStdin(readUntilEnd(m_sin)); } - if (m_fileReader.sourceUnits().empty() && !m_standardJsonInput.has_value()) + if ( + m_options.input.mode != InputMode::LanguageServer && + m_fileReader.sourceUnits().empty() && + !m_standardJsonInput.has_value() + ) solThrow(CommandLineValidationError, "All specified input files either do not exist or are not regular files."); } @@ -624,6 +631,9 @@ void CommandLineInterface::processInput() m_standardJsonInput.reset(); break; } + case InputMode::LanguageServer: + serveLSP(); + break; case InputMode::Assembler: assemble(m_options.assembly.inputLanguage, m_options.assembly.targetMachine); break; @@ -884,6 +894,13 @@ void CommandLineInterface::handleAst() } } +void CommandLineInterface::serveLSP() +{ + lsp::IOStreamTransport transport; + if (!lsp::LanguageServer{transport}.run()) + solThrow(CommandLineExecutionError, "LSP terminated abnormally."); +} + void CommandLineInterface::link() { solAssert(m_options.input.mode == InputMode::Linker, ""); diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index 9d1646e528..951731825c 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -82,6 +82,7 @@ class CommandLineInterface void printVersion(); void printLicense(); void compile(); + void serveLSP(); void link(); void writeLinkedFiles(); /// @returns the ``// -> name`` hint for library placeholders. diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 87348686c6..65c7d78621 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -59,6 +59,7 @@ static string const g_strIPFS = "ipfs"; static string const g_strLicense = "license"; static string const g_strLibraries = "libraries"; static string const g_strLink = "link"; +static string const g_strLSP = "lsp"; static string const g_strMachine = "machine"; static string const g_strMetadataHash = "metadata-hash"; static string const g_strMetadataLiteral = "metadata-literal"; @@ -135,6 +136,7 @@ static map const g_inputModeName = { {InputMode::Assembler, "assembler"}, {InputMode::StandardJson, "standard JSON"}, {InputMode::Linker, "linker"}, + {InputMode::LanguageServer, "language server (LSP)"}, }; void CommandLineParser::checkMutuallyExclusive(vector const& _optionNames) @@ -455,6 +457,7 @@ void CommandLineParser::parseOutputSelection() case InputMode::Help: case InputMode::License: case InputMode::Version: + case InputMode::LanguageServer: solAssert(false); case InputMode::Compiler: case InputMode::CompilerWithASTImport: @@ -633,6 +636,11 @@ General Information)").c_str(), "Supported Inputs is the output of the --" + g_strStandardJSON + " or the one produced by " "--" + g_strCombinedJson + " " + CombinedJsonRequests::componentName(&CombinedJsonRequests::ast)).c_str() ) + ( + g_strLSP.c_str(), + "Switch to language server mode (\"LSP\"). Allows the compiler to be used as an analysis backend " + "for your favourite IDE." + ) ; desc.add(alternativeInputModes); @@ -865,6 +873,7 @@ void CommandLineParser::processArgs() g_strStrictAssembly, g_strYul, g_strImportAst, + g_strLSP }); if (m_args.count(g_strHelp) > 0) @@ -875,6 +884,8 @@ void CommandLineParser::processArgs() m_options.input.mode = InputMode::Version; else if (m_args.count(g_strStandardJSON) > 0) m_options.input.mode = InputMode::StandardJson; + else if (m_args.count(g_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) m_options.input.mode = InputMode::Assembler; else if (m_args.count(g_strLink) > 0) @@ -910,6 +921,9 @@ void CommandLineParser::processArgs() joinOptionNames(invalidOptionsForCurrentInputMode) ); + if (m_options.input.mode == InputMode::LanguageServer) + return; + checkMutuallyExclusive({g_strColor, g_strNoColor}); array const conflictingWithStopAfter{ diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index c1a95a11f9..791e7f1c10 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -56,6 +56,7 @@ enum class InputMode StandardJson, Linker, Assembler, + LanguageServer }; struct CompilerOutputs diff --git a/test/libsolidity/lsp/didChange_template.sol b/test/libsolidity/lsp/didChange_template.sol new file mode 100644 index 0000000000..d08ba140e5 --- /dev/null +++ b/test/libsolidity/lsp/didChange_template.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +contract C +{ +} diff --git a/test/libsolidity/lsp/didOpen_with_import.sol b/test/libsolidity/lsp/didOpen_with_import.sol new file mode 100644 index 0000000000..f505ca6e5e --- /dev/null +++ b/test/libsolidity/lsp/didOpen_with_import.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +import './lib.sol'; + +contract C +{ + function f(uint a, uint b) public pure returns (uint) + { + return Lib.add(2 * a, b); + } +} diff --git a/test/libsolidity/lsp/lib.sol b/test/libsolidity/lsp/lib.sol new file mode 100644 index 0000000000..f4fb51e77b --- /dev/null +++ b/test/libsolidity/lsp/lib.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +library Lib +{ + function add(uint a, uint b) public pure returns (uint result) + { + result = a + b; + } + + function warningWithUnused() public pure + { + uint unused; + } +} diff --git a/test/libsolidity/lsp/publish_diagnostics_1.sol b/test/libsolidity/lsp/publish_diagnostics_1.sol new file mode 100644 index 0000000000..e667185122 --- /dev/null +++ b/test/libsolidity/lsp/publish_diagnostics_1.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +contract MyContract +{ + constructor() + { + uint unused; // [Warning 2072] Unused local variable. + } +} + +contract D +{ + function main() public payable returns (uint) + { + MyContract c = new MyContract(); + } +} diff --git a/test/libsolidity/lsp/publish_diagnostics_2.sol b/test/libsolidity/lsp/publish_diagnostics_2.sol new file mode 100644 index 0000000000..9686189552 --- /dev/null +++ b/test/libsolidity/lsp/publish_diagnostics_2.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +contract C +{ + function makeSomeError() public pure returns (uint res) + { + uint x = "hi"; + return; + res = 2; + } +} + +contract D +{ + function main() public payable returns (uint) + { + C c = new C(); + return c.makeSomeError(2, 3); + } +} diff --git a/test/libsolidity/lsp/publish_diagnostics_3.sol b/test/libsolidity/lsp/publish_diagnostics_3.sol new file mode 100644 index 0000000000..bb8998a6ad --- /dev/null +++ b/test/libsolidity/lsp/publish_diagnostics_3.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +abstract contract A { + function a() public virtual; +} + +contract B is A +{ +} diff --git a/test/lsp.py b/test/lsp.py new file mode 100755 index 0000000000..d558c20d95 --- /dev/null +++ b/test/lsp.py @@ -0,0 +1,874 @@ +#!/usr/bin/env python3 + +import argparse +import fnmatch +import json +import os +import subprocess +import traceback + +from typing import Any, List, Optional, Tuple, Union + +import colorama # Enables the use of SGR & CUP terminal VT sequences on Windows. +from deepdiff import DeepDiff + +# {{{ JsonRpcProcess +class BadHeader(Exception): + def __init__(self, msg: str): + super().__init__("Bad header: " + msg) + +class JsonRpcProcess: + exe_path: str + exe_args: List[str] + process: subprocess.Popen + trace_io: bool + + def __init__(self, exe_path: str, exe_args: List[str], trace_io: bool = True): + self.exe_path = exe_path + self.exe_args = exe_args + self.trace_io = trace_io + + def __enter__(self): + self.process = subprocess.Popen( + [self.exe_path, *self.exe_args], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + return self + + def __exit__(self, exception_type, exception_value, traceback) -> None: + self.process.kill() + self.process.wait(timeout=2.0) + + def trace(self, topic: str, message: str) -> None: + if self.trace_io: + print(f"{SGR_TRACE}{topic}:{SGR_RESET} {message}") + + def receive_message(self) -> Union[None, dict]: + # Note, we should make use of timeout to avoid infinite blocking if nothing is received. + CONTENT_LENGTH_HEADER = "Content-Length: " + CONTENT_TYPE_HEADER = "Content-Type: " + if self.process.stdout == None: + return None + message_size = None + while True: + # read header + line = self.process.stdout.readline() + if line == '': + # server quit + return None + line = line.decode("utf-8") + if not line.endswith("\r\n"): + raise BadHeader("missing newline") + # remove the "\r\n" + line = line[:-2] + if line == '': + break # done with the headers + if line.startswith(CONTENT_LENGTH_HEADER): + line = line[len(CONTENT_LENGTH_HEADER):] + if not line.isdigit(): + raise BadHeader("size is not int") + message_size = int(line) + elif line.startswith(CONTENT_TYPE_HEADER): + # nothing todo with type for now. + pass + else: + raise BadHeader("unknown header") + if message_size is None: + raise BadHeader("missing size") + rpc_message = self.process.stdout.read(message_size).decode("utf-8") + json_object = json.loads(rpc_message) + self.trace('receive_message', json.dumps(json_object, indent=4, sort_keys=True)) + return json_object + + def send_message(self, method_name: str, params: Optional[dict]) -> None: + if self.process.stdin == None: + return + message = { + 'jsonrpc': '2.0', + 'method': method_name, + 'params': params + } + json_string = json.dumps(obj=message) + rpc_message = f"Content-Length: {len(json_string)}\r\n\r\n{json_string}" + self.trace(f'send_message ({method_name})', json.dumps(message, indent=4, sort_keys=True)) + self.process.stdin.write(rpc_message.encode("utf-8")) + self.process.stdin.flush() + + def call_method(self, method_name: str, params: Optional[dict]) -> Any: + self.send_message(method_name, params) + return self.receive_message() + + def send_notification(self, name: str, params: Optional[dict] = None) -> None: + self.send_message(name, params) + +# }}} + +SGR_RESET = '\033[m' +SGR_TRACE = '\033[1;36m' +SGR_NOTICE = '\033[1;35m' +SGR_TEST_BEGIN = '\033[1;33m' +SGR_ASSERT_BEGIN = '\033[1;34m' +SGR_STATUS_OKAY = '\033[1;32m' +SGR_STATUS_FAIL = '\033[1;31m' + +class ExpectationFailed(Exception): + def __init__(self, actual, expected): + self.actual = actual + self.expected = expected + diff = DeepDiff(actual, expected) + super().__init__( + f"Expectation failed.\n\tExpected {expected}\n\tbut got {actual}.\n\t{diff}" + ) + +def create_cli_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(description="Solidity LSP Test suite") + parser.set_defaults(trace_io=False) + parser.add_argument( + "-T, --trace-io", + dest="trace_io", + action="store_true", + help="Be more verbose by also printing assertions." + ) + parser.set_defaults(print_assertions=False) + parser.add_argument( + "-v, --print-assertions", + dest="print_assertions", + action="store_true", + help="Be more verbose by also printing assertions." + ) + parser.add_argument( + "-t, --test-pattern", + dest="test_pattern", + type=str, + default="*", + help="Filters all available tests by matching against this test pattern (using globbing)", + nargs="?" + ) + parser.add_argument( + "solc_path", + type=str, + default="solc", + help="Path to solc binary to test against", + nargs="?" + ) + parser.add_argument( + "project_root_dir", + type=str, + default=f"{os.path.dirname(os.path.realpath(__file__))}/..", + help="Path to Solidity project's root directory (must be fully qualified).", + nargs="?" + ) + return parser + +class Counter: + total: int = 0 + passed: int = 0 + failed: int = 0 + +class SolidityLSPTestSuite: # {{{ + test_counter = Counter() + assertion_counter = Counter() + print_assertions: bool = False + trace_io: bool = False + test_pattern: str + + def __init__(self): + colorama.init() + args = create_cli_parser().parse_args() + self.solc_path = args.solc_path + self.project_root_dir = os.path.realpath(args.project_root_dir) + "/test/libsolidity/lsp" + self.project_root_uri = "file://" + self.project_root_dir + self.print_assertions = args.print_assertions + self.trace_io = args.trace_io + self.test_pattern = args.test_pattern + + print(f"{SGR_NOTICE}test pattern: {self.test_pattern}{SGR_RESET}") + + def main(self) -> int: + """ + Runs all test cases. + Returns 0 on success and the number of failing assertions (capped to 127) otherwise. + """ + all_tests = sorted([ + str(name)[5:] + for name in dir(SolidityLSPTestSuite) + if callable(getattr(SolidityLSPTestSuite, name)) and name.startswith("test_") + ]) + filtered_tests = fnmatch.filter(all_tests, self.test_pattern) + for method_name in filtered_tests: + test_fn = getattr(self, 'test_' + method_name) + title: str = test_fn.__name__[5:] + print(f"{SGR_TEST_BEGIN}Testing {title} ...{SGR_RESET}") + try: + with JsonRpcProcess(self.solc_path, ["--lsp"], trace_io=self.trace_io) as solc: + test_fn(solc) + self.test_counter.passed += 1 + except ExpectationFailed as e: + self.test_counter.failed += 1 + print(e) + print(traceback.format_exc()) + except Exception as e: # pragma pylint: disable=broad-except + self.test_counter.failed += 1 + print(f"Unhandled exception {e.__class__.__name__} caught: {e}") + print(traceback.format_exc()) + + print( + f"\n{SGR_NOTICE}Summary:{SGR_RESET}\n\n" + f" Test cases: {self.test_counter.passed} passed, {self.test_counter.failed} failed\n" + f" Assertions: {self.assertion_counter.passed} passed, {self.assertion_counter.failed} failed\n" + ) + + return min(max(self.test_counter.failed, self.assertion_counter.failed), 127) + + def setup_lsp(self, lsp: JsonRpcProcess, expose_project_root=True): + """ + Prepares the solc LSP server by calling `initialize`, + and `initialized` methods. + """ + params = { + 'processId': None, + 'rootUri': self.project_root_uri, + 'trace': 'off', + 'initializationOptions': {}, + 'capabilities': { + 'textDocument': { + 'publishDiagnostics': {'relatedInformation': True} + }, + 'workspace': { + 'applyEdit': True, + 'configuration': True, + 'didChangeConfiguration': {'dynamicRegistration': True}, + 'workspaceEdit': {'documentChanges': True}, + 'workspaceFolders': True + } + } + } + if expose_project_root == False: + params['rootUri'] = None + lsp.call_method('initialize', params) + lsp.send_notification('initialized') + + # {{{ helpers + def get_test_file_path(self, test_case_name): + return f"{self.project_root_dir}/{test_case_name}.sol" + + def get_test_file_uri(self, test_case_name): + return "file://" + self.get_test_file_path(test_case_name) + + def get_test_file_contents(self, test_case_name): + """ + Reads the file contents from disc for a given test case. + The `test_case_name` will be the basename of the file + in the test path (test/libsolidity/lsp). + """ + with open(self.get_test_file_path(test_case_name), mode="r", encoding="utf-8", newline='') as f: + return f.read() + + def require_params_for_method(self, method_name: str, message: dict) -> Any: + """ + Ensures the given RPC message does contain the + field 'method' with the given method name, + and then returns its passed params. + An exception is raised on expectation failures. + """ + assert message is not None + if 'error' in message.keys(): + code = message['error']["code"] + text = message['error']['message'] + raise RuntimeError(f"Error {code} received. {text}") + if 'method' not in message.keys(): + raise RuntimeError("No method received but something else.") + self.expect_equal(message['method'], method_name, "Ensure expected method name") + return message['params'] + + def wait_for_diagnostics(self, solc: JsonRpcProcess, count: int) -> List[dict]: + """ + Return `count` number of published diagnostic reports sorted by file URI. + """ + reports = [] + for _ in range(0, count): + message = solc.receive_message() + assert message is not None # This can happen if the server aborts early. + reports.append( + self.require_params_for_method( + 'textDocument/publishDiagnostics', + message, + ) + ) + return sorted(reports, key=lambda x: x['uri']) + + def open_file_and_wait_for_diagnostics( + self, + solc_process: JsonRpcProcess, + test_case_name: str, + max_diagnostic_reports: int = 1 + ) -> List[Any]: + """ + Opens file for given test case and waits for diagnostics to be published. + """ + assert max_diagnostic_reports > 0 + solc_process.send_message( + 'textDocument/didOpen', + { + 'textDocument': + { + 'uri': self.get_test_file_uri(test_case_name), + 'languageId': 'Solidity', + 'version': 1, + 'text': self.get_test_file_contents(test_case_name) + } + } + ) + return self.wait_for_diagnostics(solc_process, max_diagnostic_reports) + + def expect_equal(self, actual, expected, description="Equality") -> None: + self.assertion_counter.total += 1 + prefix = f"[{self.assertion_counter.total}] {SGR_ASSERT_BEGIN}{description}: " + diff = DeepDiff(actual, expected) + if len(diff) == 0: + self.assertion_counter.passed += 1 + if self.print_assertions: + print(prefix + SGR_STATUS_OKAY + 'OK' + SGR_RESET) + return + + # Failed assertions are always printed. + self.assertion_counter.failed += 1 + print(prefix + SGR_STATUS_FAIL + 'FAILED' + SGR_RESET) + raise ExpectationFailed(actual, expected) + + def expect_empty_diagnostics(self, published_diagnostics: List[dict]) -> None: + self.expect_equal(len(published_diagnostics), 1, "one publish diagnostics notification") + self.expect_equal(len(published_diagnostics[0]['diagnostics']), 0, "should not contain diagnostics") + + def expect_diagnostic( + self, + diagnostic, + code: int, + lineNo: int, + startEndColumns: Tuple[int, int] + ): + assert len(startEndColumns) == 2 + [startColumn, endColumn] = startEndColumns + self.expect_equal(diagnostic['code'], code, f'diagnostic: {code}') + self.expect_equal( + diagnostic['range'], + { + 'start': {'character': startColumn, 'line': lineNo}, + 'end': {'character': endColumn, 'line': lineNo} + }, + "diagnostic: check range" + ) + # }}} + + # {{{ actual tests + def test_publish_diagnostics_warnings(self, solc: JsonRpcProcess) -> None: + self.setup_lsp(solc) + TEST_NAME = 'publish_diagnostics_1' + published_diagnostics = self.open_file_and_wait_for_diagnostics(solc, TEST_NAME) + + self.expect_equal(len(published_diagnostics), 1, "One published_diagnostics message") + report = published_diagnostics[0] + + self.expect_equal(report['uri'], self.get_test_file_uri(TEST_NAME), "Correct file URI") + diagnostics = report['diagnostics'] + + self.expect_equal(len(diagnostics), 3, "3 diagnostic messages") + self.expect_diagnostic(diagnostics[0], code=6321, lineNo=13, startEndColumns=(44, 48)) + self.expect_diagnostic(diagnostics[1], code=2072, lineNo= 7, startEndColumns=( 8, 19)) + self.expect_diagnostic(diagnostics[2], code=2072, lineNo=15, startEndColumns=( 8, 20)) + + def test_publish_diagnostics_errors(self, solc: JsonRpcProcess) -> None: + self.setup_lsp(solc) + TEST_NAME = 'publish_diagnostics_2' + published_diagnostics = self.open_file_and_wait_for_diagnostics(solc, TEST_NAME) + + self.expect_equal(len(published_diagnostics), 1, "One published_diagnostics message") + report = published_diagnostics[0] + + self.expect_equal(report['uri'], self.get_test_file_uri(TEST_NAME), "Correct file URI") + diagnostics = report['diagnostics'] + + self.expect_equal(len(diagnostics), 3, "3 diagnostic messages") + self.expect_diagnostic(diagnostics[0], code=9574, lineNo= 7, startEndColumns=( 8, 21)) + self.expect_diagnostic(diagnostics[1], code=6777, lineNo= 8, startEndColumns=( 8, 15)) + self.expect_diagnostic(diagnostics[2], code=6160, lineNo=18, startEndColumns=(15, 36)) + + def test_publish_diagnostics_errors_multiline(self, solc: JsonRpcProcess) -> None: + self.setup_lsp(solc) + TEST_NAME = 'publish_diagnostics_3' + published_diagnostics = self.open_file_and_wait_for_diagnostics(solc, TEST_NAME) + + self.expect_equal(len(published_diagnostics), 1, "One published_diagnostics message") + report = published_diagnostics[0] + + self.expect_equal(report['uri'], self.get_test_file_uri(TEST_NAME), "Correct file URI") + diagnostics = report['diagnostics'] + + self.expect_equal(len(diagnostics), 1, "3 diagnostic messages") + self.expect_equal(diagnostics[0]['code'], 3656, "diagnostic: check code") + self.expect_equal( + diagnostics[0]['range'], + { + 'end': {'character': 1, 'line': 9}, + 'start': {'character': 0, 'line': 7} + }, + "diagnostic: check range" + ) + + def test_textDocument_didOpen_with_relative_import(self, solc: JsonRpcProcess) -> None: + self.setup_lsp(solc) + TEST_NAME = 'didOpen_with_import' + published_diagnostics = self.open_file_and_wait_for_diagnostics(solc, TEST_NAME, 2) + + self.expect_equal(len(published_diagnostics), 2, "Diagnostic reports for 2 files") + + # primary file: + report = published_diagnostics[0] + self.expect_equal(report['uri'], self.get_test_file_uri(TEST_NAME), "Correct file URI") + self.expect_equal(len(report['diagnostics']), 0, "no diagnostics") + + # imported file (./lib.sol): + report = published_diagnostics[1] + self.expect_equal(report['uri'], self.get_test_file_uri('lib'), "Correct file URI") + self.expect_equal(len(report['diagnostics']), 1, "one diagnostic") + self.expect_diagnostic(report['diagnostics'][0], code=2072, lineNo=12, startEndColumns=(8, 19)) + + def test_didChange_in_A_causing_error_in_B(self, solc: JsonRpcProcess) -> None: + # Reusing another test but now change some file that generates an error in the other. + self.test_textDocument_didOpen_with_relative_import(solc) + self.open_file_and_wait_for_diagnostics(solc, 'lib', 2) + solc.send_message( + 'textDocument/didChange', + { + 'textDocument': + { + 'uri': self.get_test_file_uri('lib') + }, + 'contentChanges': + [ + { + 'range': { + 'start': { 'line': 5, 'character': 0 }, + 'end': { 'line': 10, 'character': 0 } + }, + 'text': "" # deleting function `add` + } + ] + } + ) + published_diagnostics = self.wait_for_diagnostics(solc, 2) + self.expect_equal(len(published_diagnostics), 2, "Diagnostic reports for 2 files") + + # Main file now contains a new diagnostic + report = published_diagnostics[0] + self.expect_equal(report['uri'], self.get_test_file_uri('didOpen_with_import')) + diagnostics = report['diagnostics'] + self.expect_equal(len(diagnostics), 1, "now, no diagnostics") + self.expect_diagnostic(diagnostics[0], code=9582, lineNo=9, startEndColumns=(15, 22)) + + # The modified file retains the same diagnostics. + report = published_diagnostics[1] + self.expect_equal(report['uri'], self.get_test_file_uri('lib')) + self.expect_equal(len(report['diagnostics']), 0) + # The warning went away because the compiler aborts further processing after the error. + + def test_textDocument_didOpen_with_relative_import_without_project_url(self, solc: JsonRpcProcess) -> None: + self.setup_lsp(solc, expose_project_root=False) + TEST_NAME = 'didOpen_with_import' + published_diagnostics = self.open_file_and_wait_for_diagnostics(solc, TEST_NAME, 2) + self.verify_didOpen_with_import_diagnostics(published_diagnostics) + + def verify_didOpen_with_import_diagnostics( + self, + published_diagnostics: List[Any], + main_file_name='didOpen_with_import' + ): + self.expect_equal(len(published_diagnostics), 2, "Diagnostic reports for 2 files") + + # primary file: + report = published_diagnostics[0] + self.expect_equal(report['uri'], self.get_test_file_uri(main_file_name), "Correct file URI") + self.expect_equal(len(report['diagnostics']), 0, "one diagnostic") + + # imported file (./lib.sol): + report = published_diagnostics[1] + self.expect_equal(report['uri'], self.get_test_file_uri('lib'), "Correct file URI") + self.expect_equal(len(report['diagnostics']), 1, "one diagnostic") + self.expect_diagnostic(report['diagnostics'][0], code=2072, lineNo=12, startEndColumns=(8, 19)) + + def test_textDocument_didChange_updates_diagnostics(self, solc: JsonRpcProcess) -> None: + self.setup_lsp(solc) + TEST_NAME = 'publish_diagnostics_1' + published_diagnostics = self.open_file_and_wait_for_diagnostics(solc, TEST_NAME) + self.expect_equal(len(published_diagnostics), 1, "One published_diagnostics message") + report = published_diagnostics[0] + self.expect_equal(report['uri'], self.get_test_file_uri(TEST_NAME), "Correct file URI") + diagnostics = report['diagnostics'] + self.expect_equal(len(diagnostics), 3, "3 diagnostic messages") + self.expect_diagnostic(diagnostics[0], code=6321, lineNo=13, startEndColumns=(44, 48)) + self.expect_diagnostic(diagnostics[1], code=2072, lineNo= 7, startEndColumns=( 8, 19)) + self.expect_diagnostic(diagnostics[2], code=2072, lineNo=15, startEndColumns=( 8, 20)) + + solc.send_message( + 'textDocument/didChange', + { + 'textDocument': { + 'uri': self.get_test_file_uri(TEST_NAME) + }, + 'contentChanges': [ + { + 'range': { + 'start': { 'line': 7, 'character': 1 }, + 'end': { 'line': 8, 'character': 1 } + }, + 'text': "" + } + ] + } + ) + published_diagnostics = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(published_diagnostics), 1) + report = published_diagnostics[0] + self.expect_equal(report['uri'], self.get_test_file_uri(TEST_NAME), "Correct file URI") + diagnostics = report['diagnostics'] + self.expect_equal(len(diagnostics), 2) + self.expect_diagnostic(diagnostics[0], code=6321, lineNo=12, startEndColumns=(44, 48)) + self.expect_diagnostic(diagnostics[1], code=2072, lineNo=14, startEndColumns=( 8, 20)) + + def test_textDocument_didChange_delete_line_and_close(self, solc: JsonRpcProcess) -> None: + # Reuse this test to prepare and ensure it is as expected + self.test_textDocument_didOpen_with_relative_import(solc) + self.open_file_and_wait_for_diagnostics(solc, 'lib', 2) + # lib.sol: Fix the unused variable message by removing it. + solc.send_message( + 'textDocument/didChange', + { + 'textDocument': + { + 'uri': self.get_test_file_uri('lib') + }, + 'contentChanges': # delete the in-body statement: `uint unused;` + [ + { + 'range': + { + 'start': { 'line': 12, 'character': 1 }, + 'end': { 'line': 13, 'character': 1 } + }, + 'text': "" + } + ] + } + ) + published_diagnostics = self.wait_for_diagnostics(solc, 2) + self.expect_equal(len(published_diagnostics), 2, "published diagnostics count") + report1 = published_diagnostics[0] + self.expect_equal(report1['uri'], self.get_test_file_uri('didOpen_with_import'), "Correct file URI") + self.expect_equal(len(report1['diagnostics']), 0, "no diagnostics in didOpen_with_import.sol") + report2 = published_diagnostics[1] + self.expect_equal(report2['uri'], self.get_test_file_uri('lib'), "Correct file URI") + self.expect_equal(len(report2['diagnostics']), 0, "no diagnostics in lib.sol") + + # Now close the file and expect the warning to re-appear + solc.send_message( + 'textDocument/didClose', + { 'textDocument': { 'uri': self.get_test_file_uri('lib') }} + ) + + published_diagnostics = self.wait_for_diagnostics(solc, 2) + self.verify_didOpen_with_import_diagnostics(published_diagnostics) + + def test_textDocument_opening_two_new_files_edit_and_close(self, solc: JsonRpcProcess) -> None: + """ + Open two new files A and B, let A import B, expect no error, + then close B and now expect the error of file B not being found. + """ + + self.setup_lsp(solc) + FILE_A_URI = 'file:///a.sol' + solc.send_message('textDocument/didOpen', { + 'textDocument': { + 'uri': FILE_A_URI, + 'languageId': 'Solidity', + 'version': 1, + 'text': ''.join([ + '// SPDX-License-Identifier: UNLICENSED\n', + 'pragma solidity >=0.8.0;\n', + ]) + } + }) + reports = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(reports), 1, "one publish diagnostics notification") + self.expect_equal(len(reports[0]['diagnostics']), 0, "should not contain diagnostics") + + FILE_B_URI = 'file:///b.sol' + solc.send_message('textDocument/didOpen', { + 'textDocument': { + 'uri': FILE_B_URI, + 'languageId': 'Solidity', + 'version': 1, + 'text': ''.join([ + '// SPDX-License-Identifier: UNLICENSED\n', + 'pragma solidity >=0.8.0;\n', + ]) + } + }) + reports = self.wait_for_diagnostics(solc, 2) + self.expect_equal(len(reports), 2, "one publish diagnostics notification") + self.expect_equal(len(reports[0]['diagnostics']), 0, "should not contain diagnostics") + self.expect_equal(len(reports[1]['diagnostics']), 0, "should not contain diagnostics") + + solc.send_message('textDocument/didChange', { + 'textDocument': { + 'uri': FILE_A_URI + }, + 'contentChanges': [ + { + 'range': { + 'start': { 'line': 2, 'character': 0 }, + 'end': { 'line': 2, 'character': 0 } + }, + 'text': 'import "./b.sol";\n' + } + ] + }) + reports = self.wait_for_diagnostics(solc, 2) + self.expect_equal(len(reports), 2, "one publish diagnostics notification") + self.expect_equal(len(reports[0]['diagnostics']), 0, "should not contain diagnostics") + self.expect_equal(len(reports[1]['diagnostics']), 0, "should not contain diagnostics") + + solc.send_message( + 'textDocument/didClose', + { 'textDocument': { 'uri': FILE_B_URI }} + ) + # We only get one diagnostics message since the diagnostics for b.sol was empty. + reports = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(reports), 1, "one publish diagnostics notification") + self.expect_diagnostic(reports[0]['diagnostics'][0], 6275, 2, (0, 17)) # a.sol: File B not found + self.expect_equal(reports[0]['uri'], FILE_A_URI, "Correct uri") + + def test_textDocument_closing_virtual_file_removes_imported_real_file(self, solc: JsonRpcProcess) -> None: + """ + We open a virtual file that imports a real file with a warning. + Once we close the virtual file, the warning is removed from the diagnostics, + since the real file is not considered part of the project anymore. + """ + + self.setup_lsp(solc) + FILE_A_URI = f'file://{self.project_root_dir}/a.sol' + solc.send_message('textDocument/didOpen', { + 'textDocument': { + 'uri': FILE_A_URI, + 'languageId': 'Solidity', + 'version': 1, + 'text': + '// SPDX-License-Identifier: UNLICENSED\n' + 'pragma solidity >=0.8.0;\n' + 'import "./lib.sol";\n' + } + }) + reports = self.wait_for_diagnostics(solc, 2) + self.expect_equal(len(reports), 2, '') + self.expect_equal(len(reports[0]['diagnostics']), 0, "should not contain diagnostics") + self.expect_diagnostic(reports[1]['diagnostics'][0], 2072, 12, (8, 19)) # unused variable in lib.sol + + # Now close the file and expect the warning for lib.sol to be removed + solc.send_message( + 'textDocument/didClose', + { 'textDocument': { 'uri': FILE_A_URI }} + ) + reports = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(reports), 1, '') + self.expect_equal(reports[0]['uri'], f'file://{self.project_root_dir}/lib.sol', "") + self.expect_equal(len(reports[0]['diagnostics']), 0, "should not contain diagnostics") + + + def test_textDocument_didChange_at_eol(self, solc: JsonRpcProcess) -> None: + """ + Append at one line and insert a new one below. + """ + self.setup_lsp(solc) + FILE_NAME = 'didChange_template' + FILE_URI = self.get_test_file_uri(FILE_NAME) + solc.send_message('textDocument/didOpen', { + 'textDocument': { + 'uri': FILE_URI, + 'languageId': 'Solidity', + 'version': 1, + 'text': self.get_test_file_contents(FILE_NAME) + } + }) + published_diagnostics = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(published_diagnostics), 1, "one publish diagnostics notification") + self.expect_equal(len(published_diagnostics[0]['diagnostics']), 0, "no diagnostics") + solc.send_message('textDocument/didChange', { + 'textDocument': { + 'uri': FILE_URI + }, + 'contentChanges': [ + { + 'range': { + 'start': { 'line': 6, 'character': 0 }, + 'end': { 'line': 6, 'character': 0 } + }, + 'text': " f" + } + ] + }) + published_diagnostics = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(published_diagnostics), 1, "one publish diagnostics notification") + report2 = published_diagnostics[0] + self.expect_equal(report2['uri'], FILE_URI, "Correct file URI") + self.expect_equal(len(report2['diagnostics']), 1, "one diagnostic") + self.expect_diagnostic(report2['diagnostics'][0], 7858, 6, (1, 2)) + + solc.send_message('textDocument/didChange', { + 'textDocument': { 'uri': FILE_URI }, + 'contentChanges': [ + { + 'range': { + 'start': { 'line': 6, 'character': 2 }, + 'end': { 'line': 6, 'character': 2 } + }, + 'text': 'unction f() public {}' + } + ] + }) + published_diagnostics = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(published_diagnostics), 1, "one publish diagnostics notification") + report3 = published_diagnostics[0] + self.expect_equal(report3['uri'], FILE_URI, "Correct file URI") + self.expect_equal(len(report3['diagnostics']), 1, "one diagnostic") + self.expect_diagnostic(report3['diagnostics'][0], 4126, 6, (1, 23)) + + def test_textDocument_didChange_empty_file(self, solc: JsonRpcProcess) -> None: + """ + Starts with an empty file and changes it to look like + the didOpen_with_import test case. Then we can use + the same verification calls to ensure it worked as expected. + """ + # This FILE_NAME must be alphabetically before lib.sol to not over-complify + # the test logic in verify_didOpen_with_import_diagnostics. + FILE_NAME = 'a_new_file' + FILE_URI = self.get_test_file_uri(FILE_NAME) + self.setup_lsp(solc) + solc.send_message('textDocument/didOpen', { + 'textDocument': { + 'uri': FILE_URI, + 'languageId': 'Solidity', + 'version': 1, + 'text': '' + } + }) + reports = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(reports), 1) + report = reports[0] + published_diagnostics = report['diagnostics'] + self.expect_equal(len(published_diagnostics), 2) + self.expect_diagnostic(published_diagnostics[0], code=1878, lineNo=0, startEndColumns=(0, 0)) + self.expect_diagnostic(published_diagnostics[1], code=3420, lineNo=0, startEndColumns=(0, 0)) + solc.send_message('textDocument/didChange', { + 'textDocument': { + 'uri': self.get_test_file_uri('a_new_file') + }, + 'contentChanges': [ + { + 'range': { + 'start': { 'line': 0, 'character': 0 }, + 'end': { 'line': 0, 'character': 0 } + }, + 'text': self.get_test_file_contents('didOpen_with_import') + } + ] + }) + published_diagnostics = self.wait_for_diagnostics(solc, 2) + self.verify_didOpen_with_import_diagnostics(published_diagnostics, 'a_new_file') + + def test_textDocument_didChange_multi_line(self, solc: JsonRpcProcess) -> None: + """ + Starts with an empty file and changes it to multiple times, changing + content across lines. + """ + self.setup_lsp(solc) + FILE_NAME = 'didChange_template' + FILE_URI = self.get_test_file_uri(FILE_NAME) + solc.send_message('textDocument/didOpen', { + 'textDocument': { + 'uri': FILE_URI, + 'languageId': 'Solidity', + 'version': 1, + 'text': self.get_test_file_contents(FILE_NAME) + } + }) + published_diagnostics = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(published_diagnostics), 1, "one publish diagnostics notification") + self.expect_equal(len(published_diagnostics[0]['diagnostics']), 0, "no diagnostics") + solc.send_message('textDocument/didChange', { + 'textDocument': { 'uri': FILE_URI }, + 'contentChanges': [ + { + 'range': { + 'start': { 'line': 3, 'character': 3 }, + 'end': { 'line': 4, 'character': 1 } + }, + 'text': "tract D {\n\n uint x\n = -1; \n " + } + ] + }) + published_diagnostics = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(published_diagnostics), 1, "one publish diagnostics notification") + report2 = published_diagnostics[0] + self.expect_equal(report2['uri'], FILE_URI, "Correct file URI") + self.expect_equal(len(report2['diagnostics']), 1, "one diagnostic") + self.expect_diagnostic(report2['diagnostics'][0], 7407, 6, (3, 5)) + + # Now we are changing the part "x\n = -" of "uint x\n = -1;" + solc.send_message('textDocument/didChange', { + 'textDocument': { 'uri': FILE_URI }, + 'contentChanges': [ + { + 'range': { + 'start': { 'line': 5, 'character': 7 }, + 'end': { 'line': 6, 'character': 4 } + }, + 'text': "y\n = [\nuint(1),\n3,4]+" + } + ] + }) + published_diagnostics = self.wait_for_diagnostics(solc, 1) + self.expect_equal(len(published_diagnostics), 1, "one publish diagnostics notification") + report3 = published_diagnostics[0] + self.expect_equal(report3['uri'], FILE_URI, "Correct file URI") + self.expect_equal(len(report3['diagnostics']), 2, "two diagnostics") + diagnostic = report3['diagnostics'][0] + self.expect_equal(diagnostic['code'], 2271, 'diagnostic: 2271') + # check multi-line error code + self.expect_equal( + diagnostic['range'], + { + 'end': {'character': 6, 'line': 8}, + 'start': {'character': 3, 'line': 6} + }, + "diagnostic: check range" + ) + diagnostic = report3['diagnostics'][1] + self.expect_equal(diagnostic['code'], 7407, 'diagnostic: 7407') + # check multi-line error code + self.expect_equal( + diagnostic['range'], + { + 'end': {'character': 6, 'line': 8}, + 'start': {'character': 3, 'line': 6} + }, + "diagnostic: check range" + ) + + # }}} + # }}} + +if __name__ == "__main__": + suite = SolidityLSPTestSuite() + exit_code = suite.main() + exit(exit_code) diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 494dbbd94d..73c999f3f7 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -158,7 +158,7 @@ BOOST_AUTO_TEST_CASE(multiple_input_modes) }; string expectedMessage = "The following options are mutually exclusive: " - "--help, --license, --version, --standard-json, --link, --assemble, --strict-assembly, --yul, --import-ast. " + "--help, --license, --version, --standard-json, --link, --assemble, --strict-assembly, --yul, --import-ast, --lsp. " "Select at most one."; for (string const& mode1: inputModeOptions) From 84738eb9e6c630949cff0a21c1faedd8cbed9274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 16 Dec 2021 18:05:25 +0100 Subject: [PATCH 0209/1748] Add security policy to github's template chooser --- .github/ISSUE_TEMPLATE/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 139c117874..a5a945a675 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -9,3 +9,6 @@ contact_links: - name: Feature Request url: https://github.com/ethereum/solidity/issues/new?template=feature_request.md&projects=ethereum/solidity/43 about: Solidity language or infrastructure feature requests. + - name: Report a security vulnerability + url: https://github.com/ethereum/solidity/security/policy + about: Please review our security policy for more details. From b3d9c596cd8371728935cfaedb060ff439075315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 16 Dec 2021 18:12:04 +0100 Subject: [PATCH 0210/1748] Move issue template labels to config.yml --- .github/ISSUE_TEMPLATE/bug_report.md | 1 - .github/ISSUE_TEMPLATE/config.yml | 6 +++--- .github/ISSUE_TEMPLATE/documentation_issue.md | 1 - .github/ISSUE_TEMPLATE/feature_request.md | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 7be77f4226..36e25b1f09 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,5 @@ --- name: Bug Report -labels: ["bug :bug:"] --- no change in version. -3. A breaking change is introduced --> version is bumped to 0.5.0. -4. The 0.5.0 release is made. +1. The 0.4.0 release is made. +2. The nightly build has a version of 0.4.1 from now on. +3. Non-breaking changes are introduced --> no change in version. +4. A breaking change is introduced --> version is bumped to 0.5.0. +5. The 0.5.0 release is made. This behaviour works well with the :ref:`version pragma `. From 95f9289f2ced419639478821618f962041ac9599 Mon Sep 17 00:00:00 2001 From: Younghoon-Lee <8109h@naver.com> Date: Fri, 28 Jan 2022 01:11:35 +0900 Subject: [PATCH 0321/1748] Add blank line to make it consistency --- docs/style-guide.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 177f4a7987..1bbe6cc740 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -281,6 +281,7 @@ Yes: // ... } + contract B is Owned { // ... } @@ -846,15 +847,20 @@ Yes: constructor(uint) { } } + + contract C { constructor(uint, uint) { } } + + contract D { constructor(uint) { } } + contract A is B, C, D { uint x; From dec511aad8f7ea748455a2bdc5e3218398f04995 Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Tue, 25 Jan 2022 20:31:01 +0530 Subject: [PATCH 0322/1748] Corresponding code in the .cpp file has been commented instead of begin removed pending preliminary reviews Code generators needed fixing of the cleanup process during typecasting of bytes and integers --- Changelog.md | 2 ++ libsolidity/codegen/YulUtilFunctions.cpp | 4 ++-- .../codegen/ir/IRGeneratorForStatements.cpp | 15 +++++++----- .../codegen/ir/IRGeneratorForStatements.h | 12 ++++++---- ...nup_bytes_types_shortening_OldCodeGen.sol} | 5 ++-- ...anup_bytes_types_shortening_newCodeGen.sol | 14 +++++++++++ ...xed_log_topic_during_explicit_downcast.sol | 23 +++++++++++++++++++ ...ing_explicit_downcast_during_emissions.sol | 19 +++++++++++++++ .../userDefinedValueType/erc20.sol | 2 +- .../semanticTests/various/erc20.sol | 2 +- 10 files changed, 81 insertions(+), 17 deletions(-) rename test/libsolidity/semanticTests/cleanup/{cleanup_bytes_types_shortening.sol => cleanup_bytes_types_shortening_OldCodeGen.sol} (77%) create mode 100644 test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening_newCodeGen.sol create mode 100644 test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast.sol create mode 100644 test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast_during_emissions.sol diff --git a/Changelog.md b/Changelog.md index 571c1011d3..510feae9f2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,8 @@ Bugfixes: * Code Generator: Fix ICE when doing an explicit conversion from ``string calldata`` to ``bytes``. * Control Flow Graph: Perform proper virtual lookup for modifiers for uninitialized variable and unreachable code analysis. * Immutables: Fix wrong error when the constructor of a base contract uses ``return`` and the parent contract contains immutable variables. + * IR Generator: Add missing cleanup during the conversion of fixed bytes types to smaller fixed bytes types. + * IR Generator: Add missing cleanup for indexed event arguments of value type. * IR Generator: Fix IR syntax error when copying storage arrays of structs containing functions. * Natspec: Fix ICE when overriding a struct getter with a Natspec-documented return value and the name in the struct is different. * TypeChecker: Fix ICE when a constant variable declaration forward references a struct. diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 217ec14b0d..84f63a9e15 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -3400,11 +3400,11 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) .render(); else { - // clear for conversion to longer bytes solAssert(toCategory == Type::Category::FixedBytes, "Invalid type conversion requested."); + FixedBytesType const& to = dynamic_cast(_to); body = Whiskers("converted := (value)") - ("clean", cleanupFunction(from)) + ("clean", cleanupFunction((to.numBytes() <= from.numBytes()) ? to : from)) .render(); } break; diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 420c48baa4..cf48df4700 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1035,7 +1035,10 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) ")\n"; } else - indexedArgs.emplace_back(convert(arg, *paramTypes[i])); + { + solAssert(parameterTypes[i]->sizeOnStack() == 1, ""); + indexedArgs.emplace_back(convert(arg, *paramTypes[i], true)); + } } else { @@ -2724,14 +2727,14 @@ void IRGeneratorForStatements::assignInternalFunctionIDIfNotCalledDirectly( m_context.addToInternalDispatch(_referencedFunction); } -IRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to) +IRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to, bool _forceCleanup) { - if (_from.type() == _to) + if (_from.type() == _to && !_forceCleanup) return _from; else { IRVariable converted(m_context.newYulVariable(), _to); - define(converted, _from); + define(converted, _from, _forceCleanup); return converted; } } @@ -2763,10 +2766,10 @@ void IRGeneratorForStatements::declare(IRVariable const& _var) appendCode() << "let " << _var.commaSeparatedList() << "\n"; } -void IRGeneratorForStatements::declareAssign(IRVariable const& _lhs, IRVariable const& _rhs, bool _declare) +void IRGeneratorForStatements::declareAssign(IRVariable const& _lhs, IRVariable const& _rhs, bool _declare, bool _forceCleanup) { string output; - if (_lhs.type() == _rhs.type()) + if (_lhs.type() == _rhs.type() && !_forceCleanup) for (auto const& [stackItemName, stackItemType]: _lhs.type().stackItems()) if (stackItemType) declareAssign(_lhs.part(stackItemName), _rhs.part(stackItemName), _declare); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index 74b7def549..10e8f0b5ef 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -86,7 +86,11 @@ class IRGeneratorForStatements: public IRGeneratorForStatementsBase IRVariable evaluateExpression(Expression const& _expression, Type const& _to); /// Defines @a _var using the value of @a _value while performing type conversions, if required. - void define(IRVariable const& _var, IRVariable const& _value) { declareAssign(_var, _value, true); } + /// If @a _forceCleanup is set to true, it also cleans the value of the variable after the conversion. + void define(IRVariable const& _var, IRVariable const& _value, bool _forceCleanup = false) + { + declareAssign(_var, _value, true, _forceCleanup); + } /// @returns the name of a function that computes the value of the given constant /// and also generates the function. @@ -162,8 +166,8 @@ class IRGeneratorForStatements: public IRGeneratorForStatementsBase ); /// Generates the required conversion code and @returns an IRVariable referring to the value of @a _variable - /// converted to type @a _to. - IRVariable convert(IRVariable const& _variable, Type const& _to); + /// If @a _forceCleanup is set to true, it also cleans the value of the variable after the conversion. + IRVariable convert(IRVariable const& _variable, Type const& _to, bool _forceCleanup = false); /// @returns a Yul expression representing the current value of @a _expression, /// converted to type @a _to if it does not yet have that type. @@ -179,7 +183,7 @@ class IRGeneratorForStatements: public IRGeneratorForStatementsBase /// Declares variable @a _var. void declare(IRVariable const& _var); - void declareAssign(IRVariable const& _var, IRVariable const& _value, bool _define); + void declareAssign(IRVariable const& _var, IRVariable const& _value, bool _define, bool _forceCleanup = false); /// @returns an IRVariable with the zero /// value of @a _type. diff --git a/test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening.sol b/test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening_OldCodeGen.sol similarity index 77% rename from test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening.sol rename to test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening_OldCodeGen.sol index edae83729c..9ca68e6d0d 100644 --- a/test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening.sol +++ b/test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening_OldCodeGen.sol @@ -11,7 +11,6 @@ contract C { } } // ==== -// compileToEwasm: also -// compileViaYul: also +// compileViaYul: false // ---- -// f() -> "\xff\xff\xff\xff" +// f() -> 0xffffffff00000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening_newCodeGen.sol b/test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening_newCodeGen.sol new file mode 100644 index 0000000000..a99b82a085 --- /dev/null +++ b/test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening_newCodeGen.sol @@ -0,0 +1,14 @@ +contract C { + function f() public pure returns (bytes32 r) { + bytes4 x = 0xffffffff; + bytes2 y = bytes2(x); + assembly { + r := y + } + } +} +// ==== +// compileToEwasm: also +// compileViaYul: true +// ---- +// f() -> 0xffff000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast.sol b/test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast.sol new file mode 100644 index 0000000000..f0aa239bae --- /dev/null +++ b/test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast.sol @@ -0,0 +1,23 @@ +contract C { + function f() public pure returns (uint32 y) { + uint8 x = uint8(uint256(0x31313131313131313131313131313131)); + assembly { y := x } + } + + function g() public pure returns (bytes32 y) { + bytes1 x = bytes1(bytes16(0x31313131313131313131313131313131)); + assembly { y := x } + } + + function h() external returns (bytes32 y) { + bytes1 x; + assembly { x := sub(0,1) } + y = x; + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 0x31 +// g() -> 0x3100000000000000000000000000000000000000000000000000000000000000 +// h() -> 0xff00000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast_during_emissions.sol b/test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast_during_emissions.sol new file mode 100644 index 0000000000..df6bc2192f --- /dev/null +++ b/test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast_during_emissions.sol @@ -0,0 +1,19 @@ +contract C { + event ev0(bytes1 indexed); + constructor() { + emit ev0(bytes1(bytes16(0x31313131313131313131313131313131))); + } + function j() external { + bytes1 x; + assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 } + emit ev0(x); + } +} +// ==== +// compileViaYul: also +// ---- +// constructor() -> +// ~ emit ev0(bytes1): #"1" +// gas legacy: 168735 +// j() -> +// ~ emit ev0(bytes1): #"1" diff --git a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol index efe2ee1148..220d9d9a24 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/erc20.sol @@ -115,7 +115,7 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 442239 +// gas irOptimized: 447831 // gas legacy: 861559 // gas legacyOptimized: 420959 // totalSupply() -> 20 diff --git a/test/libsolidity/semanticTests/various/erc20.sol b/test/libsolidity/semanticTests/various/erc20.sol index 204e620d62..64a3286a94 100644 --- a/test/libsolidity/semanticTests/various/erc20.sol +++ b/test/libsolidity/semanticTests/various/erc20.sol @@ -98,7 +98,7 @@ contract ERC20 { // ---- // constructor() // ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 -// gas irOptimized: 437697 +// gas irOptimized: 443295 // gas legacy: 833310 // gas legacyOptimized: 416135 // totalSupply() -> 20 From 0f7b69432e9c7d576c57812889dba3261053a534 Mon Sep 17 00:00:00 2001 From: Nikita Stupin <18281368+nikitastupin@users.noreply.github.com> Date: Tue, 21 Sep 2021 12:04:43 +0300 Subject: [PATCH 0323/1748] Separate visibility for state variables and functions --- docs/contracts/visibility-and-getters.rst | 63 ++++++++++++++--------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/docs/contracts/visibility-and-getters.rst b/docs/contracts/visibility-and-getters.rst index f04945cfdb..8932c5079b 100644 --- a/docs/contracts/visibility-and-getters.rst +++ b/docs/contracts/visibility-and-getters.rst @@ -1,20 +1,41 @@ .. index:: ! visibility, external, public, private, internal +.. |visibility-caveat| replace:: Making something ``private`` or ``internal`` only prevents other contracts from reading or modifying the information, but it will still be visible to the whole world outside of the blockchain. + .. _visibility-and-getters: ********************** Visibility and Getters ********************** -Solidity knows two kinds of function calls: internal -ones that do not create an actual EVM call (also called -a "message call") and external -ones that do. Because of that, there are four types of visibility for -functions and state variables. +State Variable Visibility +========================= + +``public`` + Public state variables differ from internal ones only in that the compiler automatically generates + :ref:`getter functions` for them, which allows other contracts to read their values. + When used within the same contract, the external access (e.g. ``this.x``) invokes the getter + while internal access (e.g. ``x``) gets the variable value directly from storage. + Setter functions are not generated so other contracts cannot directly modify their values. + +``internal`` + Internal state variables can only be accessed from within the contract they are defined in + and in derived contracts. + They cannot be accessed externally. + This is the default visibility level for state variables. + +``private`` + Private state variables are like internal ones but they are not visible in derived contracts. + +.. warning:: + |visibility-caveat| -Functions have to be specified as being ``external``, -``public``, ``internal`` or ``private``. -For state variables, ``external`` is not possible. +Function Visibility +=================== + +Solidity knows two kinds of function calls: external ones that do create an actual EVM message call and internal ones that do not. +Furthermore, internal functions can be made inaccessible to derived contracts. +This gives rise to four types of visibility for functions. ``external`` External functions are part of the contract interface, @@ -24,27 +45,19 @@ For state variables, ``external`` is not possible. ``public`` Public functions are part of the contract interface - and can be either called internally or via - messages. For public state variables, an automatic getter - function (see below) is generated. + and can be either called internally or via message calls. ``internal`` - Those functions and state variables can only be - accessed internally (i.e. from within the current contract - or contracts deriving from it), without using ``this``. - This is the default visibility level for state variables. + Internal functions can only be accessed from within the current contract + or contracts deriving from it. + They cannot be accessed externally. + Since they are not exposed to the outside through the contract's ABI, they can take parameters of internal types like mappings or storage references. ``private`` - Private functions and state variables are only - visible for the contract they are defined in and not in - derived contracts. - -.. note:: - Everything that is inside a contract is visible to - all observers external to the blockchain. Making something ``private`` - only prevents other contracts from reading or modifying - the information, but it will still be visible to the - whole world outside of the blockchain. + Private functions are like internal ones but they are not visible in derived contracts. + +.. warning:: + |visibility-caveat| The visibility specifier is given after the type for state variables and between parameter list and From 0fe5811459bb25078e471ceeec475eaf49374d21 Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Mon, 24 Jan 2022 11:56:27 +0100 Subject: [PATCH 0324/1748] Fixed a ICE on calldata to struct member copy --- Changelog.md | 1 + .../codegen/ir/IRGeneratorForStatements.cpp | 7 +- .../structs/copy_from_calldata.sol | 38 ++++++++ .../structs/copy_from_storage.sol | 24 +++++ .../copy_struct_array_from_storage.sol | 96 +++++++++++++++++++ .../structs/function_type_copy.sol | 44 +++++++++ .../msg_data_to_struct_member_copy.sol | 45 +++++++++ .../array/copy_from_function_type.sol | 9 ++ 8 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/semanticTests/structs/copy_from_calldata.sol create mode 100644 test/libsolidity/semanticTests/structs/copy_from_storage.sol create mode 100644 test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol create mode 100644 test/libsolidity/semanticTests/structs/function_type_copy.sol create mode 100644 test/libsolidity/semanticTests/structs/msg_data_to_struct_member_copy.sol create mode 100644 test/libsolidity/syntaxTests/array/copy_from_function_type.sol diff --git a/Changelog.md b/Changelog.md index 510feae9f2..a49aedea4c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -18,6 +18,7 @@ Bugfixes: * Immutables: Fix wrong error when the constructor of a base contract uses ``return`` and the parent contract contains immutable variables. * IR Generator: Add missing cleanup during the conversion of fixed bytes types to smaller fixed bytes types. * IR Generator: Add missing cleanup for indexed event arguments of value type. + * IR Generator: Fix internal error when copying reference types in calldata and storage to struct or array members in memory. * IR Generator: Fix IR syntax error when copying storage arrays of structs containing functions. * Natspec: Fix ICE when overriding a struct getter with a Natspec-documented return value and the name in the struct is different. * TypeChecker: Fix ICE when a constant variable declaration forward references a struct. diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index cf48df4700..d68bc39c60 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2985,8 +2985,11 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable { solAssert(_lvalue.type.sizeOnStack() == 1); auto const* valueReferenceType = dynamic_cast(&_value.type()); - solAssert(valueReferenceType && valueReferenceType->dataStoredIn(DataLocation::Memory)); - appendCode() << "mstore(" + _memory.address + ", " + _value.part("mpos").name() + ")\n"; + solAssert(valueReferenceType); + if (valueReferenceType->dataStoredIn(DataLocation::Memory)) + appendCode() << "mstore(" + _memory.address + ", " + _value.part("mpos").name() + ")\n"; + else + appendCode() << "mstore(" + _memory.address + ", " + m_utils.conversionFunction(_value.type(), _lvalue.type) + "(" + _value.commaSeparatedList() + "))\n"; } }, [&](IRLValue::Stack const& _stack) { assign(_stack.variable, _value); }, diff --git a/test/libsolidity/semanticTests/structs/copy_from_calldata.sol b/test/libsolidity/semanticTests/structs/copy_from_calldata.sol new file mode 100644 index 0000000000..bfe6fc949c --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_from_calldata.sol @@ -0,0 +1,38 @@ +// Example from https://github.com/ethereum/solidity/issues/12558 +pragma abicoder v2; +contract C { + function f(uint[] calldata a) external returns (uint[][] memory) { + uint[][] memory m = new uint[][](2); + m[0] = a; + + return m; + } +} +contract Test { + C immutable c = new C(); + + function test() external returns (bool) { + uint[] memory arr = new uint[](4); + + arr[0] = 13; + arr[1] = 14; + arr[2] = 15; + arr[3] = 16; + + uint[][] memory ret = c.f(arr); + assert(ret.length == 2); + assert(ret[0].length == 4); + assert(ret[0][0] == 13); + assert(ret[0][1] == 14); + assert(ret[0][2] == 15); + assert(ret[0][3] == 16); + assert(ret[1].length == 0); + + return true; + } +} +// ==== +// EVMVersion: >homestead +// compileViaYul: also +// ---- +// test() -> true diff --git a/test/libsolidity/semanticTests/structs/copy_from_storage.sol b/test/libsolidity/semanticTests/structs/copy_from_storage.sol new file mode 100644 index 0000000000..d4a970bdce --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_from_storage.sol @@ -0,0 +1,24 @@ +pragma abicoder v2; +// Example from https://github.com/ethereum/solidity/issues/12558 +struct S { + uint x; +} + +contract C { + S sStorage; + constructor() { + sStorage.x = 13; + } + + function f() external returns (S[] memory) { + S[] memory sMemory = new S[](1); + + sMemory[0] = sStorage; + + return sMemory; + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> 0x20, 1, 13 diff --git a/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol b/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol new file mode 100644 index 0000000000..7bbe495ce2 --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol @@ -0,0 +1,96 @@ +pragma abicoder v2; + +struct S { uint value; } + +contract Test { + S[][] a; + S[] b; + + constructor() { + a.push(); + a[0].push(S(1)); + a[0].push(S(2)); + a[0].push(S(3)); + + b.push(S(4)); + b.push(S(5)); + b.push(S(6)); + b.push(S(7)); + } + + function test1() external returns (bool) { + a.push(); + a[1] = b; + + assert(a.length == 2); + assert(a[0].length == 3); + assert(a[1].length == 4); + assert(a[1][0].value == 4); + assert(a[1][1].value == 5); + assert(a[1][2].value == 6); + assert(a[1][3].value == 7); + + return true; + } + + function test2() external returns (bool) { + S[][] memory temp = new S[][](2); + + temp = a; + + assert(temp.length == 2); + assert(temp[0].length == 3); + assert(temp[1].length == 4); + assert(temp[1][0].value == 4); + assert(temp[1][1].value == 5); + assert(temp[1][2].value == 6); + assert(temp[1][3].value == 7); + + return true; + } + + function test3() external returns (bool) { + S[][] memory temp = new S[][](2); + + temp[0] = a[0]; + temp[1] = a[1]; + + assert(temp.length == 2); + assert(temp[0].length == 3); + assert(temp[1].length == 4); + assert(temp[1][0].value == 4); + assert(temp[1][1].value == 5); + assert(temp[1][2].value == 6); + assert(temp[1][3].value == 7); + + return true; + } + + function test4() external returns (bool) { + S[][] memory temp = new S[][](2); + + temp[0] = a[0]; + temp[1] = b; + + assert(temp.length == 2); + assert(temp[0].length == 3); + assert(temp[1].length == 4); + assert(temp[1][0].value == 4); + assert(temp[1][1].value == 5); + assert(temp[1][2].value == 6); + assert(temp[1][3].value == 7); + + return true; + } +} +// ==== +// EVMVersion: >homestead +// compileViaYul: also +// ---- +// test1() -> true +// gas irOptimized: 150618 +// gas legacy: 150266 +// gas legacyOptimized: 149875 +// test2() -> true +// test3() -> true +// test4() -> true diff --git a/test/libsolidity/semanticTests/structs/function_type_copy.sol b/test/libsolidity/semanticTests/structs/function_type_copy.sol new file mode 100644 index 0000000000..79fe5ef4c8 --- /dev/null +++ b/test/libsolidity/semanticTests/structs/function_type_copy.sol @@ -0,0 +1,44 @@ +pragma abicoder v2; +struct S { + function () external[] functions; +} + +contract C { + function f(function () external[] calldata functions) external returns (S memory) { + S memory s; + s.functions = functions; + return s; + } +} + +contract Test { + C immutable c = new C(); + + function test() external returns (bool) { + function() external[] memory functions = new function() external[](3); + + functions[0] = this.random1; + functions[1] = this.random2; + functions[2] = this.random3; + + S memory ret = c.f(functions); + + assert(ret.functions.length == 3); + assert(ret.functions[0] == this.random1); + assert(ret.functions[1] == this.random2); + assert(ret.functions[2] == this.random3); + + return true; + } + function random1() external { + } + function random2() external { + } + function random3() external { + } +} +// ==== +// EVMVersion: >homestead +// compileViaYul: also +// ---- +// test() -> true diff --git a/test/libsolidity/semanticTests/structs/msg_data_to_struct_member_copy.sol b/test/libsolidity/semanticTests/structs/msg_data_to_struct_member_copy.sol new file mode 100644 index 0000000000..f28bbf477f --- /dev/null +++ b/test/libsolidity/semanticTests/structs/msg_data_to_struct_member_copy.sol @@ -0,0 +1,45 @@ +pragma abicoder v2; + +struct St0 { + bytes el0; +} +contract C { + function f() external returns (St0 memory) { + St0 memory x; + x.el0 = msg.data; + return x; + } + + function g() external returns (St0 memory) { + bytes memory temp = msg.data; + St0 memory x; + x.el0 = temp; + return x; + } + + function hashes() external returns (bytes4, bytes4) { + return (this.f.selector, this.g.selector); + } + + function large(uint256, uint256, uint256, uint256) external returns (St0 memory) { + St0 memory x; + x.el0 = msg.data; + return x; + } + + function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) { + bytes memory temp = msg.data; + St0 memory x; + x.el0 = temp; + return x; + } + +} +// ==== +// compileViaYul: also +// ---- +// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000 +// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000 +// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000 +// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000 +// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/syntaxTests/array/copy_from_function_type.sol b/test/libsolidity/syntaxTests/array/copy_from_function_type.sol new file mode 100644 index 0000000000..b795094683 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/copy_from_function_type.sol @@ -0,0 +1,9 @@ +// Example from https://github.com/ethereum/solidity/issues/12558 +pragma abicoder v2; +contract C { + function() external[1][] s0; + constructor(function() external[1][] memory i0) + { + i0[0] = s0[1]; + } +} From f1ce1528bb988fe3d51f3cc98e16dd1b5eaa9d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 28 Jan 2022 21:46:01 +0100 Subject: [PATCH 0325/1748] Update the release checklist to use the build+publish commands for solc-js --- ReleaseChecklist.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index b95ea32a94..39a3d9a324 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -66,7 +66,8 @@ ### 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. - - [ ] Run ``npm run updateBinary && npm publish`` in the updated ``solc-js`` repository. + - [ ] Run ``npm run build:tarball`` in the updated ``solc-js`` repository to create ``solc-.tgz``. Inspect the tarball to ensure that it contains an up to date compiler binary. + - [ ] Run ``npm run publish:tarball`` to publish the newly created tarball. - [ ] Create a tag using ``git tag --annotate v$VERSION`` and push it with ``git push --tags``. ### Post-release From 8728971354c15b1a8147726fa8c3efe8c801f0ee Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 31 Jan 2022 19:07:01 +0100 Subject: [PATCH 0326/1748] Correct type of address.code --- docs/types/value-types.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 215a18ceec..30a8577963 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -331,7 +331,9 @@ on ``call``. * ``code`` and ``codehash`` -You can query the deployed code for any smart contract. Use ``code`` to get the EVM bytecode as a string, which might be empty. Use ``codehash`` get the Keccak-256 hash of that code. +You can query the deployed code for any smart contract. Use ``.code`` to get the EVM bytecode as a +``bytes memory``, which might be empty. Use ``.codehash`` get the Keccak-256 hash of that code +(as a ``bytes32``). Note that ``addr.codehash`` is cheaper than using ``keccak256(addr.code)``. .. note:: All contracts can be converted to ``address`` type, so it is possible to query the balance of the From 4259e1bb7021d28931bf3d3f5973e32431f2c837 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 31 Jan 2022 19:18:32 +0100 Subject: [PATCH 0327/1748] Fix changelog --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index a49aedea4c..e75e2c710e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -15,7 +15,7 @@ Bugfixes: * Code Generator: Fix ICE when accessing the members of external functions occupying more than two stack slots. * Code Generator: Fix ICE when doing an explicit conversion from ``string calldata`` to ``bytes``. * Control Flow Graph: Perform proper virtual lookup for modifiers for uninitialized variable and unreachable code analysis. - * Immutables: Fix wrong error when the constructor of a base contract uses ``return`` and the parent contract contains immutable variables. + * Immutables: Fix wrong error when the constructor of a base contract uses ``return`` and the derived contract contains immutable variables. * IR Generator: Add missing cleanup during the conversion of fixed bytes types to smaller fixed bytes types. * IR Generator: Add missing cleanup for indexed event arguments of value type. * IR Generator: Fix internal error when copying reference types in calldata and storage to struct or array members in memory. From 73470aed6afb172f189a550b79e310c9cac8c680 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 3 Nov 2021 16:10:14 +0100 Subject: [PATCH 0328/1748] Fix util::valueOrDefault. --- libsolutil/CommonData.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index 0d5a75282e..b117c27728 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -267,17 +267,22 @@ template< typename MapType, typename KeyType, typename ValueType = std::decay_t().find(std::declval())->second)> const&, - typename AllowCopyType = void* + typename AllowCopyType = std::conditional_t || std::is_pointer_v, detail::allow_copy, void*> > -decltype(auto) valueOrDefault(MapType&& _map, KeyType const& _key, ValueType&& _defaultValue = {}, AllowCopyType = nullptr) +decltype(auto) valueOrDefault( + MapType&& _map, + KeyType const& _key, + ValueType&& _defaultValue = {}, + AllowCopyType = {} +) { auto it = _map.find(_key); static_assert( std::is_same_v || - std::is_reference_vsecond)>, + std::is_reference_v(_defaultValue) : it->second)>, "valueOrDefault does not allow copies by default. Pass allow_copy as additional argument, if you want to allow copies." ); - return (it == _map.end()) ? _defaultValue : it->second; + return (it == _map.end()) ? std::forward(_defaultValue) : it->second; } namespace detail From 8bcc4ee7d1a65f4732549f31cd7d5e8194c6c260 Mon Sep 17 00:00:00 2001 From: franzihei Date: Mon, 31 Jan 2022 15:32:49 +0100 Subject: [PATCH 0329/1748] Adding a few resources --- docs/resources.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/resources.rst b/docs/resources.rst index 5b8d0013ab..a3b8d17e08 100644 --- a/docs/resources.rst +++ b/docs/resources.rst @@ -14,7 +14,7 @@ General Resources * `Solidity Compiler Developers Chat `_ * `Awesome Solidity `_ * `Solidity by Example `_ - +* `Solidity Documentation Community Translations `_ Integrated (Ethereum) Development Environments ============================================== @@ -28,15 +28,15 @@ Integrated (Ethereum) Development Environments * `Embark `_ Developer platform for building and deploying decentralized applications. + * `Foundry `_ + Fast, portable and modular toolkit for Ethereum application development written in Rust. + * `Hardhat `_ Ethereum development environment with local Ethereum network, debugging features and plugin ecosystem. * `Remix `_ Browser-based IDE with integrated compiler and Solidity runtime environment without server-side components. - * `Scaffold-ETH `_ - Ethereum development stack focused on fast product iterations. - * `Truffle `_ Ethereum development framework. @@ -112,6 +112,9 @@ Solidity Tools * `PIET `_ A tool to develop, audit and use Solidity smart contracts through a simple graphical interface. +* `Scaffold-ETH `_ + Forkable Ethereum development stack focused on fast product iterations. + * `sol2uml `_ Unified Modeling Language (UML) class diagram generator for Solidity contracts. @@ -130,6 +133,9 @@ Solidity Tools * `Solhint `_ Solidity linter that provides security, style guide and best practice rules for smart contract validation. +* `Sourcify `_ + Decentralized automated contract verification service and public repository of contract metadata. + * `Sūrya `_ Utility tool for smart contract systems, offering a number of visual outputs and information about the contracts' structure. Also supports querying the function call graph. From e2711b7fabcbf3af0c15e415778d821c1581d913 Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Tue, 25 Jan 2022 20:31:01 +0530 Subject: [PATCH 0330/1748] Corresponding code in the .cpp file has been commented instead of begin removed pending preliminary reviews Code generators needed fixing of the cleanup process during typecasting of bytes and integers --- .../codegen/ir/IRGeneratorForStatements.cpp | 37 ++++++++++++------- .../codegen/ir/IRGeneratorForStatements.h | 30 +++++++++++---- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index d68bc39c60..86d00dbc9c 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -805,8 +805,8 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp) if (auto type = dynamic_cast(commonType)) isSigned = type->isSigned(); - string args = expressionAsType(_binOp.leftExpression(), *commonType, true); - args += ", " + expressionAsType(_binOp.rightExpression(), *commonType, true); + string args = expressionAsCleanedType(_binOp.leftExpression(), *commonType); + args += ", " + expressionAsCleanedType(_binOp.rightExpression(), *commonType); auto functionType = dynamic_cast(commonType); solAssert(functionType ? (op == Token::Equal || op == Token::NotEqual) : true, "Invalid function pointer comparison!"); @@ -1037,7 +1037,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) else { solAssert(parameterTypes[i]->sizeOnStack() == 1, ""); - indexedArgs.emplace_back(convert(arg, *paramTypes[i], true)); + indexedArgs.emplace_back(convertAndCleanup(arg, *parameterTypes[i])); } } else @@ -2727,32 +2727,43 @@ void IRGeneratorForStatements::assignInternalFunctionIDIfNotCalledDirectly( m_context.addToInternalDispatch(_referencedFunction); } -IRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to, bool _forceCleanup) +IRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to) { - if (_from.type() == _to && !_forceCleanup) + if (_from.type() == _to) return _from; else { IRVariable converted(m_context.newYulVariable(), _to); - define(converted, _from, _forceCleanup); + define(converted, _from); return converted; } } -std::string IRGeneratorForStatements::expressionAsType(Expression const& _expression, Type const& _to, bool _forceCleanup) +IRVariable IRGeneratorForStatements::convertAndCleanup(IRVariable const& _from, Type const& _to) +{ + IRVariable converted(m_context.newYulVariable(), _to); + defineAndCleanup(converted, _from); + return converted; +} + +std::string IRGeneratorForStatements::expressionAsType(Expression const& _expression, Type const& _to) { IRVariable from(_expression); if (from.type() == _to) - { - if (_forceCleanup) - return m_utils.cleanupFunction(_to) + "(" + from.commaSeparatedList() + ")"; - else - return from.commaSeparatedList(); - } + return from.commaSeparatedList(); else return m_utils.conversionFunction(from.type(), _to) + "(" + from.commaSeparatedList() + ")"; } +std::string IRGeneratorForStatements::expressionAsCleanedType(Expression const& _expression, Type const& _to) +{ + IRVariable from(_expression); + if (from.type() == _to) + return m_utils.cleanupFunction(_to) + "(" + expressionAsType(_expression, _to) + ")"; + else + return expressionAsType(_expression, _to) ; +} + std::ostream& IRGeneratorForStatements::define(IRVariable const& _var) { if (_var.type().sizeOnStack() > 0) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index 10e8f0b5ef..11f8b3c846 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -86,10 +86,19 @@ class IRGeneratorForStatements: public IRGeneratorForStatementsBase IRVariable evaluateExpression(Expression const& _expression, Type const& _to); /// Defines @a _var using the value of @a _value while performing type conversions, if required. - /// If @a _forceCleanup is set to true, it also cleans the value of the variable after the conversion. - void define(IRVariable const& _var, IRVariable const& _value, bool _forceCleanup = false) + void define(IRVariable const& _var, IRVariable const& _value) { - declareAssign(_var, _value, true, _forceCleanup); + bool _declare = true; + declareAssign(_var, _value, _declare); + } + + /// Defines @a _var using the value of @a _value while performing type conversions, if required. + /// It also cleans the value of the variable. + void defineAndCleanup(IRVariable const& _var, IRVariable const& _value) + { + bool _forceCleanup = true; + bool _declare = true; + declareAssign(_var, _value, _declare, _forceCleanup); } /// @returns the name of a function that computes the value of the given constant @@ -166,13 +175,20 @@ class IRGeneratorForStatements: public IRGeneratorForStatementsBase ); /// Generates the required conversion code and @returns an IRVariable referring to the value of @a _variable - /// If @a _forceCleanup is set to true, it also cleans the value of the variable after the conversion. - IRVariable convert(IRVariable const& _variable, Type const& _to, bool _forceCleanup = false); + IRVariable convert(IRVariable const& _variable, Type const& _to); + + /// Generates the required conversion code and @returns an IRVariable referring to the value of @a _variable + /// It also cleans the value of the variable. + IRVariable convertAndCleanup(IRVariable const& _from, Type const& _to); + + /// @returns a Yul expression representing the current value of @a _expression, + /// converted to type @a _to if it does not yet have that type. + std::string expressionAsType(Expression const& _expression, Type const& _to); /// @returns a Yul expression representing the current value of @a _expression, /// converted to type @a _to if it does not yet have that type. - /// If @a _forceCleanup is set to true, it also cleans the value, in case it already has type @a _to. - std::string expressionAsType(Expression const& _expression, Type const& _to, bool _forceCleanup = false); + /// It also cleans the value, in case it already has type @a _to. + std::string expressionAsCleanedType(Expression const& _expression, Type const& _to); /// @returns an output stream that can be used to define @a _var using a function call or /// single stack slot expression. From 1528d4b9e4e8de6771ce15da90341e96d08dba86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 1 Feb 2022 14:34:03 +0100 Subject: [PATCH 0331/1748] perpetual-pools: Switch the test to our fork (original repo is gone) --- test/externalTests/perpetual-pools.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/perpetual-pools.sh b/test/externalTests/perpetual-pools.sh index 6c4af4937b..e1ee9af8f5 100755 --- a/test/externalTests/perpetual-pools.sh +++ b/test/externalTests/perpetual-pools.sh @@ -34,7 +34,7 @@ function test_fn { yarn test; } function perpetual_pools_test { - local repo="https://github.com/tracer-protocol/perpetual-pools-contracts" + 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" From 6788f77541729e3ab2bc9e41dda66c2c06540b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 1 Feb 2022 15:25:13 +0100 Subject: [PATCH 0332/1748] Add missing SELECTED_PRESETS argument to some of the recently added external tests --- test/externalTests/bleeps.sh | 1 + test/externalTests/elementfi.sh | 1 + test/externalTests/trident.sh | 1 + test/externalTests/uniswap.sh | 1 + 4 files changed, 4 insertions(+) diff --git a/test/externalTests/bleeps.sh b/test/externalTests/bleeps.sh index df0e5e39e0..a4d1efa625 100755 --- a/test/externalTests/bleeps.sh +++ b/test/externalTests/bleeps.sh @@ -27,6 +27,7 @@ source test/externalTests/common.sh verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" +SELECTED_PRESETS="$3" function compile_fn { npm run compile; } function test_fn { npm run test; } diff --git a/test/externalTests/elementfi.sh b/test/externalTests/elementfi.sh index 7227ce37e2..f52a13ca67 100755 --- a/test/externalTests/elementfi.sh +++ b/test/externalTests/elementfi.sh @@ -27,6 +27,7 @@ source test/externalTests/common.sh verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" +SELECTED_PRESETS="$3" function compile_fn { npm run build; } function test_fn { npm run test; } diff --git a/test/externalTests/trident.sh b/test/externalTests/trident.sh index 26c3d38104..8e6f35ae33 100755 --- a/test/externalTests/trident.sh +++ b/test/externalTests/trident.sh @@ -27,6 +27,7 @@ source test/externalTests/common.sh verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" +SELECTED_PRESETS="$3" function compile_fn { yarn build; } diff --git a/test/externalTests/uniswap.sh b/test/externalTests/uniswap.sh index b3baad1a32..96a5d2b63b 100755 --- a/test/externalTests/uniswap.sh +++ b/test/externalTests/uniswap.sh @@ -27,6 +27,7 @@ source test/externalTests/common.sh verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" +SELECTED_PRESETS="$3" function compile_fn { yarn compile; } function test_fn { UPDATE_SNAPSHOT=1 npx hardhat test; } From 57800529d1f54daa5d5c961532362dd50a62405d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 1 Feb 2022 16:40:08 +0100 Subject: [PATCH 0333/1748] bleeps: Switch to the main branch --- test/externalTests/bleeps.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/externalTests/bleeps.sh b/test/externalTests/bleeps.sh index a4d1efa625..70f69d4603 100755 --- a/test/externalTests/bleeps.sh +++ b/test/externalTests/bleeps.sh @@ -35,8 +35,8 @@ function test_fn { npm run test; } function bleeps_test { local repo="https://github.com/wighawag/bleeps" - local ref_type=tag - local ref=bleeps_migrations # TODO: There's a 0.4.19 contract in 'main' that would need patching for the latest compiler. + local ref_type=branch + local ref=main local config_file="hardhat.config.ts" local config_var=config From e1a90b829e395d5356812d461322e465506c501e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 1 Feb 2022 16:40:28 +0100 Subject: [PATCH 0334/1748] bleeps: Patch WETH9.sol for 0.8.x --- test/externalTests/bleeps.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/externalTests/bleeps.sh b/test/externalTests/bleeps.sh index 70f69d4603..d005cf8efb 100755 --- a/test/externalTests/bleeps.sh +++ b/test/externalTests/bleeps.sh @@ -66,6 +66,12 @@ function bleeps_test pushd "contracts/" sed -i 's|"bleeps-common": "workspace:\*",|"bleeps-common": "file:../common-lib/",|g' package.json + sed -i 's/function() public/fallback() external/g' src/externals/WETH9.sol + sed -i 's/this\.balance/address(this).balance/g' src/externals/WETH9.sol + sed -i 's/uint(-1)/type(uint).max/g' src/externals/WETH9.sol + sed -i 's/msg\.sender\.transfer(/payable(msg.sender).transfer(/g' src/externals/WETH9.sol + sed -i 's/^\s*\(Deposit\|Withdrawal\|Approval\|Transfer\)(/emit \1(/g' src/externals/WETH9.sol + neutralize_package_lock neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" From 1e0a695d241dcf430c485dfdfb1d9e2b454fdb7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 1 Feb 2022 17:01:10 +0100 Subject: [PATCH 0335/1748] Disable bleeps external test until it gets fixed upstream --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 143a692fdb..44b44bb012 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1468,7 +1468,8 @@ workflows: - t_ems_ext: *job_native_test_ext_trident - t_ems_ext: *job_native_test_ext_euler - t_ems_ext: *job_native_test_ext_yield_liquidator - - t_ems_ext: *job_native_test_ext_bleeps + # Disabled until we have a fix for https://github.com/wighawag/bleeps/issues/2 + #-t_ems_ext: *job_native_test_ext_bleeps - t_ems_ext: *job_native_test_ext_pool_together - t_ems_ext: *job_native_test_ext_perpetual_pools - t_ems_ext: *job_native_test_ext_uniswap From 9043621747de80cfb6b4a5e890f062d6e962d27d Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Fri, 28 Jan 2022 23:27:05 +0530 Subject: [PATCH 0336/1748] Changed occurences of isByteArray() to isByteArrayOrString(). The idea is to, in a future commit, replace such occurences of isByteArrayOrString() which are required to return True only for Bytes type with a new isByteArray() function. --- .../analysis/DeclarationTypeChecker.cpp | 2 +- libsolidity/analysis/TypeChecker.cpp | 4 +- libsolidity/ast/Types.cpp | 26 ++++---- libsolidity/ast/Types.h | 8 +-- libsolidity/codegen/ABIFunctions.cpp | 24 +++---- libsolidity/codegen/ArrayUtils.cpp | 58 ++++++++-------- libsolidity/codegen/CompilerUtils.cpp | 12 ++-- libsolidity/codegen/ExpressionCompiler.cpp | 14 ++-- libsolidity/codegen/YulUtilFunctions.cpp | 66 +++++++++---------- libsolidity/codegen/ir/IRGenerator.cpp | 4 +- .../codegen/ir/IRGeneratorForStatements.cpp | 6 +- libsolidity/formal/SMTEncoder.cpp | 10 +-- libsolidity/formal/SymbolicTypes.cpp | 2 +- libsolidity/interface/ABI.cpp | 2 +- libsolidity/interface/StorageLayout.cpp | 2 +- 15 files changed, 120 insertions(+), 120 deletions(-) diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index 7a4aa99427..ba989972cb 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -441,7 +441,7 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) { bool allowed = false; if (auto arrayType = dynamic_cast(type)) - allowed = arrayType->isByteArray(); + allowed = arrayType->isByteArrayOrString(); if (!allowed) m_errorReporter.fatalTypeError(9259_error, _variable.location(), "Only constants of value type and byte array type are implemented."); } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index f3ba2884b7..1a07d6ded0 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1783,7 +1783,7 @@ Type const* TypeChecker::typeCheckTypeConversionAndRetrieveReturnType( ( ( resultArrayType->isPointer() || - (argArrayType->isByteArray() && resultArrayType->isByteArray()) + (argArrayType->isByteArrayOrString() && resultArrayType->isByteArrayOrString()) ) && resultArrayType->location() == DataLocation::Storage ), @@ -1791,7 +1791,7 @@ Type const* TypeChecker::typeCheckTypeConversionAndRetrieveReturnType( ); else solAssert( - argArrayType->isByteArray() && !argArrayType->isString() && resultType->category() == Type::Category::FixedBytes, + argArrayType->isByteArrayOrString() && !argArrayType->isString() && resultType->category() == Type::Category::FixedBytes, "" ); } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index fb31a93030..f50210ff55 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1206,7 +1206,7 @@ BoolResult StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) ); return arrayType->location() != DataLocation::CallData && - arrayType->isByteArray() && + arrayType->isByteArrayOrString() && !(arrayType->dataStoredIn(DataLocation::Storage) && arrayType->isPointer()); } else @@ -1530,7 +1530,7 @@ BoolResult ArrayType::isImplicitlyConvertibleTo(Type const& _convertTo) const if (_convertTo.category() != category()) return false; auto& convertTo = dynamic_cast(_convertTo); - if (convertTo.isByteArray() != isByteArray() || convertTo.isString() != isString()) + if (convertTo.isByteArrayOrString() != isByteArrayOrString() || convertTo.isString() != isString()) return false; // memory/calldata to storage can be converted, but only to a direct storage reference if (convertTo.location() == DataLocation::Storage && location() != DataLocation::Storage && convertTo.isPointer()) @@ -1571,11 +1571,11 @@ BoolResult ArrayType::isExplicitlyConvertibleTo(Type const& _convertTo) const return true; // allow conversion bytes <-> string and bytes -> bytesNN if (_convertTo.category() != category()) - return isByteArray() && !isString() && _convertTo.category() == Type::Category::FixedBytes; + return isByteArrayOrString() && !isString() && _convertTo.category() == Type::Category::FixedBytes; auto& convertTo = dynamic_cast(_convertTo); if (convertTo.location() != location()) return false; - if (!isByteArray() || !convertTo.isByteArray()) + if (!isByteArrayOrString() || !convertTo.isByteArrayOrString()) return false; return true; } @@ -1585,7 +1585,7 @@ string ArrayType::richIdentifier() const string id; if (isString()) id = "t_string"; - else if (isByteArray()) + else if (isByteArrayOrString()) id = "t_bytes"; else { @@ -1608,7 +1608,7 @@ bool ArrayType::operator==(Type const& _other) const ArrayType const& other = dynamic_cast(_other); if ( !ReferenceType::operator==(other) || - other.isByteArray() != isByteArray() || + other.isByteArrayOrString() != isByteArrayOrString() || other.isString() != isString() || other.isDynamicallySized() != isDynamicallySized() ) @@ -1751,7 +1751,7 @@ string ArrayType::toString(bool _short) const string ret; if (isString()) ret = "string"; - else if (isByteArray()) + else if (isByteArrayOrString()) ret = "bytes"; else { @@ -1770,7 +1770,7 @@ string ArrayType::canonicalName() const string ret; if (isString()) ret = "string"; - else if (isByteArray()) + else if (isByteArrayOrString()) ret = "bytes"; else { @@ -1784,7 +1784,7 @@ string ArrayType::canonicalName() const string ArrayType::signatureInExternalFunction(bool _structsByName) const { - if (isByteArray()) + if (isByteArrayOrString()) return canonicalName(); else { @@ -1899,7 +1899,7 @@ u256 ArrayType::memoryDataSize() const { solAssert(!isDynamicallySized(), ""); solAssert(m_location == DataLocation::Memory, ""); - solAssert(!isByteArray(), ""); + solAssert(!isByteArrayOrString(), ""); bigint size = bigint(m_length) * m_baseType->memoryHeadSize(); solAssert(size <= numeric_limits::max(), "Array size does not fit u256."); return u256(size); @@ -2701,7 +2701,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): } else if (auto arrayType = dynamic_cast(returnType)) { - if (arrayType->isByteArray()) + if (arrayType->isByteArrayOrString()) // Return byte arrays as whole. break; returnType = arrayType->baseType(); @@ -2720,7 +2720,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): if (member.type->category() != Category::Mapping) { if (auto arrayType = dynamic_cast(member.type)) - if (!arrayType->isByteArray()) + if (!arrayType->isByteArrayOrString()) continue; m_returnParameterTypes.push_back(TypeProvider::withLocationIfReference( DataLocation::Memory, @@ -3813,7 +3813,7 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons } else if ( auto const* arrayType = dynamic_cast(m_actualType); - arrayType && arrayType->isByteArray() + arrayType && arrayType->isByteArrayOrString() ) members.emplace_back("concat", TypeProvider::function( TypePointers{}, diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index f15da58ab3..e34c114057 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -838,7 +838,7 @@ class ArrayType: public ReferenceType BoolResult validForLocation(DataLocation _loc) const override; /// @returns true if this is a byte array or a string - bool isByteArray() const { return m_arrayKind != ArrayKind::Ordinary; } + bool isByteArrayOrString() const { return m_arrayKind != ArrayKind::Ordinary; } /// @returns true if this is a string bool isString() const { return m_arrayKind == ArrayKind::String; } Type const* baseType() const { solAssert(!!m_baseType, ""); return m_baseType; } @@ -849,11 +849,11 @@ class ArrayType: public ReferenceType std::unique_ptr copyForLocation(DataLocation _location, bool _isPointer) const override; /// The offset to advance in calldata to move from one array element to the next. - unsigned calldataStride() const { return isByteArray() ? 1 : m_baseType->calldataHeadSize(); } + unsigned calldataStride() const { return isByteArrayOrString() ? 1 : m_baseType->calldataHeadSize(); } /// The offset to advance in memory to move from one array element to the next. - unsigned memoryStride() const { return isByteArray() ? 1 : m_baseType->memoryHeadSize(); } + unsigned memoryStride() const { return isByteArrayOrString() ? 1 : m_baseType->memoryHeadSize(); } /// The offset to advance in storage to move from one array element to the next. - unsigned storageStride() const { return isByteArray() ? 1 : m_baseType->storageBytes(); } + unsigned storageStride() const { return isByteArrayOrString() ? 1 : m_baseType->storageBytes(); } void clearCache() const override; diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index 97cf3425db..65f9e1723a 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -312,7 +312,7 @@ string ABIFunctions::abiEncodingFunction( { case DataLocation::CallData: if ( - fromArray->isByteArray() || + fromArray->isByteArrayOrString() || *fromArray->baseType() == *TypeProvider::uint256() || *fromArray->baseType() == FixedBytesType(32) ) @@ -320,7 +320,7 @@ string ABIFunctions::abiEncodingFunction( else return abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options); case DataLocation::Memory: - if (fromArray->isByteArray()) + if (fromArray->isByteArrayOrString()) return abiEncodingFunctionMemoryByteArray(*fromArray, *toArray, _options); else return abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options); @@ -448,7 +448,7 @@ string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup( solAssert(fromArrayType.location() == DataLocation::CallData, ""); solAssert( - fromArrayType.isByteArray() || + fromArrayType.isByteArrayOrString() || *fromArrayType.baseType() == *TypeProvider::uint256() || *fromArrayType.baseType() == FixedBytesType(32), "" @@ -468,7 +468,7 @@ string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup( _to.identifier() + _options.toFunctionNameSuffix(); return createFunction(functionName, [&]() { - bool needsPadding = _options.padded && fromArrayType.isByteArray(); + bool needsPadding = _options.padded && fromArrayType.isByteArrayOrString(); if (fromArrayType.isDynamicallySized()) { Whiskers templ(R"( @@ -482,7 +482,7 @@ string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup( )"); templ("storeLength", arrayStoreLengthForEncodingFunction(toArrayType, _options)); templ("functionName", functionName); - if (fromArrayType.isByteArray() || fromArrayType.calldataStride() == 1) + if (fromArrayType.isByteArrayOrString() || fromArrayType.calldataStride() == 1) templ("scaleLengthByStride", ""); else templ("scaleLengthByStride", @@ -536,7 +536,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray( solAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), ""); solAssert(_from.length() == _to.length(), ""); - solAssert(!_from.isByteArray(), ""); + solAssert(!_from.isByteArrayOrString(), ""); if (_from.dataStoredIn(DataLocation::Storage)) solAssert(_from.baseType()->storageBytes() > 16, ""); @@ -647,10 +647,10 @@ string ABIFunctions::abiEncodingFunctionMemoryByteArray( solAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), ""); solAssert(_from.length() == _to.length(), ""); solAssert(_from.dataStoredIn(DataLocation::Memory), ""); - solAssert(_from.isByteArray(), ""); + solAssert(_from.isByteArrayOrString(), ""); return createFunction(functionName, [&]() { - solAssert(_to.isByteArray(), ""); + solAssert(_to.isByteArrayOrString(), ""); Whiskers templ(R"( function (value, pos) -> end { let length := (value) @@ -686,9 +686,9 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray( solAssert(_from.dataStoredIn(DataLocation::Storage), ""); return createFunction(functionName, [&]() { - if (_from.isByteArray()) + if (_from.isByteArrayOrString()) { - solAssert(_to.isByteArray(), ""); + solAssert(_to.isByteArrayOrString(), ""); Whiskers templ(R"( // -> function (value, pos) -> ret { @@ -1168,7 +1168,7 @@ string ABIFunctions::abiDecodingFunctionArray(ArrayType const& _type, bool _from string ABIFunctions::abiDecodingFunctionArrayAvailableLength(ArrayType const& _type, bool _fromMemory) { solAssert(_type.dataStoredIn(DataLocation::Memory), ""); - if (_type.isByteArray()) + if (_type.isByteArrayOrString()) return abiDecodingFunctionByteArrayAvailableLength(_type, _fromMemory); solAssert(_type.calldataStride() > 0, ""); @@ -1275,7 +1275,7 @@ string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type) string ABIFunctions::abiDecodingFunctionByteArrayAvailableLength(ArrayType const& _type, bool _fromMemory) { solAssert(_type.dataStoredIn(DataLocation::Memory), ""); - solAssert(_type.isByteArray(), ""); + solAssert(_type.isByteArrayOrString(), ""); string functionName = "abi_decode_available_length_" + diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index 27afe14985..d2691c8779 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -50,8 +50,8 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons solAssert(_targetType.location() == DataLocation::Storage, ""); Type const* uint256 = TypeProvider::uint256(); - Type const* targetBaseType = _targetType.isByteArray() ? uint256 : _targetType.baseType(); - Type const* sourceBaseType = _sourceType.isByteArray() ? uint256 : _sourceType.baseType(); + Type const* targetBaseType = _targetType.isByteArrayOrString() ? uint256 : _targetType.baseType(); + Type const* sourceBaseType = _sourceType.isByteArrayOrString() ? uint256 : _sourceType.baseType(); // TODO unroll loop for small sizes @@ -97,7 +97,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons // stack: target_ref source_ref source_length target_ref target_length if (_targetType.isDynamicallySized()) // store new target length - if (!_targetType.isByteArray()) + if (!_targetType.isByteArrayOrString()) // Otherwise, length will be stored below. _context << Instruction::DUP3 << Instruction::DUP3 << Instruction::SSTORE; if (sourceBaseType->category() == Type::Category::Mapping) @@ -126,7 +126,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons evmasm::AssemblyItem copyLoopEndWithoutByteOffset = _context.newTag(); // special case for short byte arrays: Store them together with their length. - if (_targetType.isByteArray()) + if (_targetType.isByteArrayOrString()) { // stack: target_ref target_data_end source_length target_data_pos source_ref _context << Instruction::DUP3; @@ -141,7 +141,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons _context << Instruction::DUP3 << u256(31) << Instruction::LT; evmasm::AssemblyItem longByteArray = _context.appendConditionalJump(); // store the short byte array - solAssert(_sourceType.isByteArray(), ""); + solAssert(_sourceType.isByteArrayOrString(), ""); if (_sourceType.location() == DataLocation::Storage) { // just copy the slot, it contains length and data @@ -323,7 +323,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord { if (!_sourceType.isDynamicallySized()) m_context << _sourceType.length(); - if (!_sourceType.isByteArray()) + if (!_sourceType.isByteArrayOrString()) convertLengthToSize(_sourceType); string routine = "calldatacopy(target, source, len)\n"; @@ -375,14 +375,14 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord m_context << Instruction::SWAP1 << u256(32) << Instruction::ADD; m_context << Instruction::SWAP1; } - if (!_sourceType.isByteArray()) + if (!_sourceType.isByteArrayOrString()) convertLengthToSize(_sourceType); // stack: m_context << Instruction::DUP1 << Instruction::DUP4 << Instruction::DUP4; // We can resort to copying full 32 bytes only if // - the length is known to be a multiple of 32 or // - we will pad to full 32 bytes later anyway. - if (!_sourceType.isByteArray() || _padToWordBoundaries) + if (!_sourceType.isByteArrayOrString() || _padToWordBoundaries) utils.memoryCopy32(); else utils.memoryCopy(); @@ -390,7 +390,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord m_context << Instruction::SWAP1 << Instruction::POP; // stack: - bool paddingNeeded = _padToWordBoundaries && _sourceType.isByteArray(); + bool paddingNeeded = _padToWordBoundaries && _sourceType.isByteArrayOrString(); if (paddingNeeded) { @@ -446,7 +446,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord m_context << Instruction::DUP1 << Instruction::ISZERO; evmasm::AssemblyItem loopEnd = m_context.appendConditionalJump(); // Special case for tightly-stored byte arrays - if (_sourceType.isByteArray()) + if (_sourceType.isByteArrayOrString()) { // stack here: memory_offset storage_offset length m_context << Instruction::DUP1 << u256(31) << Instruction::LT; @@ -482,14 +482,14 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord } // stack here: memory_end_offset storage_data_offset memory_offset - bool haveByteOffset = !_sourceType.isByteArray() && storageBytes <= 16; + bool haveByteOffset = !_sourceType.isByteArrayOrString() && storageBytes <= 16; if (haveByteOffset) m_context << u256(0) << Instruction::SWAP1; // stack here: memory_end_offset storage_data_offset [storage_byte_offset] memory_offset evmasm::AssemblyItem loopStart = m_context.newTag(); m_context << loopStart; // load and store - if (_sourceType.isByteArray()) + if (_sourceType.isByteArrayOrString()) { // Packed both in storage and memory. m_context << Instruction::DUP2 << Instruction::SLOAD; @@ -528,12 +528,12 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord // stack here: memory_end_offset storage_data_offset [storage_byte_offset] memory_offset if (haveByteOffset) m_context << Instruction::SWAP1 << Instruction::POP; - if (!_sourceType.isByteArray()) + if (!_sourceType.isByteArrayOrString()) { solAssert(_sourceType.calldataStride() % 32 == 0, ""); solAssert(_sourceType.memoryStride() % 32 == 0, ""); } - if (_padToWordBoundaries && _sourceType.isByteArray()) + if (_padToWordBoundaries && _sourceType.isByteArrayOrString()) { // memory_end_offset - start is the actual length (we want to compute the ceil of). // memory_offset - start is its next multiple of 32, but it might be off by 32. @@ -624,7 +624,7 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const m_context << u256(0) << Instruction::DUP3 << Instruction::SSTORE; // Special case: short byte arrays are stored togeher with their length evmasm::AssemblyItem endTag = m_context.newTag(); - if (_type.isByteArray()) + if (_type.isByteArrayOrString()) { // stack: ref old_length m_context << Instruction::DUP1 << u256(31) << Instruction::LT; @@ -664,7 +664,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const ArrayType const& _type = dynamic_cast(*type); solAssert(_type.location() == DataLocation::Storage, ""); solAssert(_type.isDynamicallySized(), ""); - if (!_type.isByteArray() && _type.baseType()->storageBytes() < 32) + if (!_type.isByteArrayOrString() && _type.baseType()->storageBytes() < 32) solAssert(_type.baseType()->isValueType(), "Invalid storage size for non-value type."); unsigned stackHeightStart = _context.stackHeight(); @@ -677,7 +677,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const solAssert(_context.stackHeight() - stackHeightStart == 3 - 2, "2"); // Special case for short byte arrays, they are stored together with their length - if (_type.isByteArray()) + if (_type.isByteArrayOrString()) { evmasm::AssemblyItem regularPath = _context.newTag(); // We start by a large case-distinction about the old and new length of the byte array. @@ -766,7 +766,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const // stack: ref new_length old_length // store new length _context << Instruction::DUP2; - if (_type.isByteArray()) + if (_type.isByteArrayOrString()) // For a "long" byte array, store length as 2*length+1 _context << Instruction::DUP1 << Instruction::ADD << u256(1) << Instruction::ADD; _context << Instruction::DUP4 << Instruction::SSTORE; @@ -806,10 +806,10 @@ void ArrayUtils::incrementDynamicArraySize(ArrayType const& _type) const { solAssert(_type.location() == DataLocation::Storage, ""); solAssert(_type.isDynamicallySized(), ""); - if (!_type.isByteArray() && _type.baseType()->storageBytes() < 32) + if (!_type.isByteArrayOrString() && _type.baseType()->storageBytes() < 32) solAssert(_type.baseType()->isValueType(), "Invalid storage size for non-value type."); - if (_type.isByteArray()) + if (_type.isByteArrayOrString()) { // We almost always just add 2 (length of byte arrays is shifted left by one) // except for the case where we transition from a short byte array @@ -850,10 +850,10 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const { solAssert(_type.location() == DataLocation::Storage, ""); solAssert(_type.isDynamicallySized(), ""); - if (!_type.isByteArray() && _type.baseType()->storageBytes() < 32) + if (!_type.isByteArrayOrString() && _type.baseType()->storageBytes() < 32) solAssert(_type.baseType()->isValueType(), "Invalid storage size for non-value type."); - if (_type.isByteArray()) + if (_type.isByteArrayOrString()) { m_context << Instruction::DUP1 << Instruction::SLOAD << Instruction::DUP1; m_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1); @@ -999,7 +999,7 @@ void ArrayUtils::convertLengthToSize(ArrayType const& _arrayType, bool _pad) con } else { - if (!_arrayType.isByteArray()) + if (!_arrayType.isByteArrayOrString()) { if (_arrayType.location() == DataLocation::Memory) m_context << _arrayType.memoryStride(); @@ -1031,7 +1031,7 @@ void ArrayUtils::retrieveLength(ArrayType const& _arrayType, unsigned _stackDept break; case DataLocation::Storage: m_context << Instruction::SLOAD; - if (_arrayType.isByteArray()) + if (_arrayType.isByteArrayOrString()) m_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1); break; } @@ -1062,7 +1062,7 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck, b { case DataLocation::Memory: // stack: - if (!_arrayType.isByteArray()) + if (!_arrayType.isByteArrayOrString()) m_context << u256(_arrayType.memoryHeadSize()) << Instruction::MUL; if (_arrayType.isDynamicallySized()) m_context << u256(32) << Instruction::ADD; @@ -1071,7 +1071,7 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck, b m_context << Instruction::ADD; break; case DataLocation::CallData: - if (!_arrayType.isByteArray()) + if (!_arrayType.isByteArrayOrString()) { m_context << _arrayType.calldataStride(); m_context << Instruction::MUL; @@ -1090,7 +1090,7 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck, b // stack: [] evmasm::AssemblyItem endTag = m_context.newTag(); - if (_arrayType.isByteArray()) + if (_arrayType.isByteArrayOrString()) { // Special case of short byte arrays. m_context << Instruction::SWAP1; @@ -1153,7 +1153,7 @@ void ArrayUtils::accessCallDataArrayElement(ArrayType const& _arrayType, bool _d { solAssert(_arrayType.baseType()->storageBytes() <= 32, ""); if ( - !_arrayType.isByteArray() && + !_arrayType.isByteArrayOrString() && _arrayType.baseType()->storageBytes() < 32 && m_context.useABICoderV2() ) @@ -1165,7 +1165,7 @@ void ArrayUtils::accessCallDataArrayElement(ArrayType const& _arrayType, bool _d CompilerUtils(m_context).loadFromMemoryDynamic( *_arrayType.baseType(), true, - !_arrayType.isByteArray(), + !_arrayType.isByteArrayOrString(), false ); } diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 1876b6ac06..ba678878f2 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -970,7 +970,7 @@ void CompilerUtils::convertType( else if (targetTypeCategory == Type::Category::Array) { auto const& arrayType = dynamic_cast(_targetType); - solAssert(arrayType.isByteArray()); + solAssert(arrayType.isByteArrayOrString()); size_t storageSize = 32 + ((data.size() + 31) / 32) * 32; allocateMemory(storageSize); // stack: mempos @@ -992,7 +992,7 @@ void CompilerUtils::convertType( if (_targetType.category() == Type::Category::FixedBytes) { solAssert( - typeOnStack.isByteArray() && !typeOnStack.isString(), + typeOnStack.isByteArrayOrString() && !typeOnStack.isString(), "Array types other than bytes not convertible to bytesNN." ); solAssert(typeOnStack.isDynamicallySized()); @@ -1019,7 +1019,7 @@ void CompilerUtils::convertType( case DataLocation::Storage: // Other cases are done explicitly in LValue::storeValue, and only possible by assignment. solAssert( - (targetType.isPointer() || (typeOnStack.isByteArray() && targetType.isByteArray())) && + (targetType.isPointer() || (typeOnStack.isByteArrayOrString() && targetType.isByteArrayOrString())) && typeOnStack.location() == DataLocation::Storage, "Invalid conversion to storage type." ); @@ -1105,7 +1105,7 @@ void CompilerUtils::convertType( } case DataLocation::CallData: solAssert( - ((targetType.isByteArray() && typeOnStack.isByteArray()) || _typeOnStack == _targetType) && + ((targetType.isByteArrayOrString() && typeOnStack.isByteArrayOrString()) || _typeOnStack == _targetType) && typeOnStack.location() == DataLocation::CallData, "Invalid conversion to calldata type." ); @@ -1119,7 +1119,7 @@ void CompilerUtils::convertType( if (_targetType.category() == Type::Category::FixedBytes) { solAssert( - typeOnStack.arrayType().isByteArray() && !typeOnStack.arrayType().isString(), + typeOnStack.arrayType().isByteArrayOrString() && !typeOnStack.arrayType().isString(), "Array types other than bytes not convertible to bytesNN." ); solAssert(typeOnStack.isDynamicallySized()); @@ -1142,7 +1142,7 @@ void CompilerUtils::convertType( auto const& targetArrayType = dynamic_cast(_targetType); solAssert( typeOnStack.arrayType().isImplicitlyConvertibleTo(targetArrayType) || - (typeOnStack.arrayType().isByteArray() && targetArrayType.isByteArray()) + (typeOnStack.arrayType().isByteArrayOrString() && targetArrayType.isByteArrayOrString()) ); solAssert( typeOnStack.arrayType().dataStoredIn(DataLocation::CallData) && diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index a76d1f3d9b..da3022251f 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -153,7 +153,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& if (paramTypes[i]->isDynamicallySized()) { solAssert( - dynamic_cast(*paramTypes[i]).isByteArray(), + dynamic_cast(*paramTypes[i]).isByteArrayOrString(), "Expected string or byte array for mapping key type" ); @@ -239,7 +239,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& if (returnTypes[i]->category() == Type::Category::Mapping) continue; if (auto arrayType = dynamic_cast(returnTypes[i])) - if (!arrayType->isByteArray()) + if (!arrayType->isByteArrayOrString()) continue; pair const& offsets = structType->storageOffsetsOfMember(names[i]); m_context << Instruction::DUP1 << u256(offsets.first) << Instruction::ADD << u256(offsets.second); @@ -1047,7 +1047,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // stack: ArrayReference (newLength-1) ArrayUtils(m_context).accessIndex(*arrayType, false); - if (arrayType->isByteArray()) + if (arrayType->isByteArrayOrString()) setLValue(_functionCall); else setLValueToStorageItem(_functionCall); @@ -1084,7 +1084,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) utils().moveToStackTop(1 + type->sizeOnStack()); utils().moveToStackTop(1 + type->sizeOnStack()); // stack: argValue storageSlot slotOffset - if (!arrayType->isByteArray()) + if (!arrayType->isByteArrayOrString()) StorageItem(m_context, *paramType).storeValue(*type, _functionCall.location(), true); else StorageByteArrayElement(m_context).storeValue(*type, _functionCall.location(), true); @@ -1165,7 +1165,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // update free memory pointer m_context << Instruction::DUP1; // Stack: memptr requested_length requested_length - if (arrayType.isByteArray()) + if (arrayType.isByteArrayOrString()) // Round up to multiple of 32 m_context << u256(31) << Instruction::ADD << u256(31) << Instruction::NOT << Instruction::AND; else @@ -2086,7 +2086,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) { case DataLocation::Storage: ArrayUtils(m_context).accessIndex(arrayType); - if (arrayType.isByteArray()) + if (arrayType.isByteArrayOrString()) { solAssert(!arrayType.isString(), "Index access to string is not allowed."); setLValue(_indexAccess); @@ -2096,7 +2096,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) break; case DataLocation::Memory: ArrayUtils(m_context).accessIndex(arrayType); - setLValue(_indexAccess, *_indexAccess.annotation().type, !arrayType.isByteArray()); + setLValue(_indexAccess, *_indexAccess.annotation().type, !arrayType.isByteArrayOrString()); break; case DataLocation::CallData: ArrayUtils(m_context).accessCallDataArrayElement(arrayType); diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 84f63a9e15..3c79b64b46 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -1183,8 +1183,8 @@ string YulUtilFunctions::arrayLengthFunction(ArrayType const& _type) w("calldata", _type.location() == DataLocation::CallData); if (_type.location() == DataLocation::Storage) { - w("byteArray", _type.isByteArray()); - if (_type.isByteArray()) + w("byteArray", _type.isByteArrayOrString()); + if (_type.isByteArrayOrString()) w("extractByteArrayLength", extractByteArrayLengthFunction()); } @@ -1220,7 +1220,7 @@ std::string YulUtilFunctions::resizeArrayFunction(ArrayType const& _type) solAssert(_type.location() == DataLocation::Storage, ""); solUnimplementedAssert(_type.baseType()->storageBytes() <= 32); - if (_type.isByteArray()) + if (_type.isByteArrayOrString()) return resizeDynamicByteArrayFunction(_type); string functionName = "resize_array_" + _type.identifier(); @@ -1259,7 +1259,7 @@ string YulUtilFunctions::cleanUpStorageArrayEndFunction(ArrayType const& _type) { solAssert(_type.location() == DataLocation::Storage, ""); solAssert(_type.baseType()->category() != Type::Category::Mapping, ""); - solAssert(!_type.isByteArray(), ""); + solAssert(!_type.isByteArrayOrString(), ""); solUnimplementedAssert(_type.baseType()->storageBytes() <= 32); string functionName = "cleanup_storage_array_end_" + _type.identifier(); @@ -1319,7 +1319,7 @@ string YulUtilFunctions::resizeDynamicByteArrayFunction(ArrayType const& _type) string YulUtilFunctions::cleanUpDynamicByteArrayEndSlotsFunction(ArrayType const& _type) { - solAssert(_type.isByteArray(), ""); + solAssert(_type.isByteArrayOrString(), ""); solAssert(_type.isDynamicallySized(), ""); string functionName = "clean_up_bytearray_end_slots_" + _type.identifier(); @@ -1479,7 +1479,7 @@ string YulUtilFunctions::storageArrayPopFunction(ArrayType const& _type) solAssert(_type.location() == DataLocation::Storage, ""); solAssert(_type.isDynamicallySized(), ""); solUnimplementedAssert(_type.baseType()->storageBytes() <= 32, "Base type is not yet implemented."); - if (_type.isByteArray()) + if (_type.isByteArrayOrString()) return storageByteArrayPopFunction(_type); string functionName = "array_pop_" + _type.identifier(); @@ -1509,7 +1509,7 @@ string YulUtilFunctions::storageByteArrayPopFunction(ArrayType const& _type) { solAssert(_type.location() == DataLocation::Storage, ""); solAssert(_type.isDynamicallySized(), ""); - solAssert(_type.isByteArray(), ""); + solAssert(_type.isByteArrayOrString(), ""); string functionName = "byte_array_pop_" + _type.identifier(); return m_functionCollector.createFunction(functionName, [&]() { @@ -1566,7 +1566,7 @@ string YulUtilFunctions::storageArrayPushFunction(ArrayType const& _type, Type c return m_functionCollector.createFunction(functionName, [&]() { return Whiskers(R"( function (array ) { - + let data := sload(array) let oldLen := (data) if iszero(lt(oldLen, )) { () } @@ -1598,20 +1598,20 @@ string YulUtilFunctions::storageArrayPushFunction(ArrayType const& _type, Type c let slot, offset := (array, oldLen) (slot, offset ) } - + let oldLen := sload(array) if iszero(lt(oldLen, )) { () } sstore(array, add(oldLen, 1)) let slot, offset := (array, oldLen) (slot, offset ) - + })") ("functionName", functionName) ("values", _fromType->sizeOnStack() == 0 ? "" : ", " + suffixedVariableNameList("value", 0, _fromType->sizeOnStack())) ("panic", panicFunction(PanicCode::ResourceError)) - ("extractByteArrayLength", _type.isByteArray() ? extractByteArrayLengthFunction() : "") + ("extractByteArrayLength", _type.isByteArrayOrString() ? extractByteArrayLengthFunction() : "") ("dataAreaFunction", arrayDataAreaFunction(_type)) - ("isByteArray", _type.isByteArray()) + ("isByteArrayOrString", _type.isByteArrayOrString()) ("indexAccess", storageArrayIndexAccessFunction(_type)) ("storeValue", updateStorageValueFunction(*_fromType, *_type.baseType())) ("maxArrayLength", (u256(1) << 64).str()) @@ -1642,9 +1642,9 @@ string YulUtilFunctions::storageArrayPushZeroFunction(ArrayType const& _type) slot, offset := (array, oldLen) })") ("functionName", functionName) - ("isBytes", _type.isByteArray()) - ("increaseBytesSize", _type.isByteArray() ? increaseByteArraySizeFunction(_type) : "") - ("extractLength", _type.isByteArray() ? extractByteArrayLengthFunction() : "") + ("isBytes", _type.isByteArrayOrString()) + ("increaseBytesSize", _type.isByteArrayOrString() ? increaseByteArraySizeFunction(_type) : "") + ("extractLength", _type.isByteArrayOrString() ? extractByteArrayLengthFunction() : "") ("panic", panicFunction(PanicCode::ResourceError)) ("fetchLength", arrayLengthFunction(_type)) ("indexAccess", storageArrayIndexAccessFunction(_type)) @@ -1795,7 +1795,7 @@ string YulUtilFunctions::copyArrayToStorageFunction(ArrayType const& _fromType, if (!_toType.isDynamicallySized()) solAssert(!_fromType.isDynamicallySized() && _fromType.length() <= _toType.length(), ""); - if (_fromType.isByteArray()) + if (_fromType.isByteArrayOrString()) return copyByteArrayToStorageFunction(_fromType, _toType); if (_fromType.dataStoredIn(DataLocation::Storage) && _toType.baseType()->isValueType()) return copyValueArrayStorageToStorageFunction(_fromType, _toType); @@ -1902,8 +1902,8 @@ string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromTy *_fromType.copyForLocation(_toType.location(), _toType.isPointer()) == dynamic_cast(_toType), "" ); - solAssert(_fromType.isByteArray(), ""); - solAssert(_toType.isByteArray(), ""); + solAssert(_fromType.isByteArrayOrString(), ""); + solAssert(_toType.isByteArrayOrString(), ""); string functionName = "copy_byte_array_to_storage_from_" + _fromType.identifier() + "_to_" + _toType.identifier(); return m_functionCollector.createFunction(functionName, [&](){ @@ -1980,8 +1980,8 @@ string YulUtilFunctions::copyValueArrayStorageToStorageFunction(ArrayType const& solAssert(_toType.baseType()->isValueType(), ""); solAssert(_fromType.baseType()->isImplicitlyConvertibleTo(*_toType.baseType()), ""); - solAssert(!_fromType.isByteArray(), ""); - solAssert(!_toType.isByteArray(), ""); + solAssert(!_fromType.isByteArrayOrString(), ""); + solAssert(!_toType.isByteArrayOrString(), ""); solAssert(_fromType.dataStoredIn(DataLocation::Storage), ""); solAssert(_toType.dataStoredIn(DataLocation::Storage), ""); @@ -2155,7 +2155,7 @@ string YulUtilFunctions::arrayConvertLengthToSize(ArrayType const& _type) })") ("functionName", functionName) ("stride", to_string(_type.location() == DataLocation::Memory ? _type.memoryStride() : _type.calldataStride())) - ("byteArray", _type.isByteArray()) + ("byteArray", _type.isByteArrayOrString()) ("mul", overflowCheckedIntMulFunction(*TypeProvider::uint256())) .render(); default: @@ -2187,7 +2187,7 @@ string YulUtilFunctions::arrayAllocationSizeFunction(ArrayType const& _type) )"); w("functionName", functionName); w("panic", panicFunction(PanicCode::ResourceError)); - w("byteArray", _type.isByteArray()); + w("byteArray", _type.isByteArrayOrString()); w("roundUp", roundUpFunction()); w("dynamic", _type.isDynamicallySized()); return w.render(); @@ -2262,7 +2262,7 @@ string YulUtilFunctions::storageArrayIndexAccessFunction(ArrayType const& _type) ("dataAreaFunc", arrayDataAreaFunction(_type)) ("indexAccessNoChecks", longByteArrayStorageIndexAccessNoCheckFunction()) ("multipleItemsPerSlot", _type.baseType()->storageBytes() <= 16) - ("isBytesArray", _type.isByteArray()) + ("isBytesArray", _type.isByteArrayOrString()) ("storageSize", _type.baseType()->storageSize().str()) ("storageBytes", toString(_type.baseType()->storageBytes())) ("itemsPerSlot", to_string(32 / _type.baseType()->storageBytes())) @@ -2376,7 +2376,7 @@ string YulUtilFunctions::accessCalldataTailFunction(Type const& _type) string YulUtilFunctions::nextArrayElementFunction(ArrayType const& _type) { - solAssert(!_type.isByteArray(), ""); + solAssert(!_type.isByteArrayOrString(), ""); if (_type.dataStoredIn(DataLocation::Storage)) solAssert(_type.baseType()->storageBytes() > 16, ""); string functionName = "array_nextElement_" + _type.identifier(); @@ -2447,7 +2447,7 @@ string YulUtilFunctions::copyArrayFromStorageToMemoryFunction(ArrayType const& _ solAssert(_to.memoryStride() == 32, ""); solAssert(_to.baseType()->dataStoredIn(DataLocation::Memory), ""); solAssert(_from.baseType()->dataStoredIn(DataLocation::Storage), ""); - solAssert(!_from.isByteArray(), ""); + solAssert(!_from.isByteArrayOrString(), ""); solAssert(*_to.withLocation(DataLocation::Storage, _from.isPointer()) == _from, ""); return Whiskers(R"( function (slot) -> memPtr { @@ -2755,7 +2755,7 @@ string YulUtilFunctions::updateStorageValueFunction( solAssert(_fromType.category() == Type::Category::StringLiteral, ""); solAssert(toReferenceType->category() == Type::Category::Array, ""); auto const& toArrayType = dynamic_cast(*toReferenceType); - solAssert(toArrayType.isByteArray(), ""); + solAssert(toArrayType.isByteArrayOrString(), ""); return Whiskers(R"( function (slot, offset) { @@ -3216,7 +3216,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) auto const& fromType = dynamic_cast(_from); if (_to.category() == Type::Category::FixedBytes) { - solAssert(fromType.arrayType().isByteArray(), "Array types other than bytes not convertible to bytesNN."); + solAssert(fromType.arrayType().isByteArrayOrString(), "Array types other than bytes not convertible to bytesNN."); return bytesToFixedBytesConversionFunction(fromType.arrayType(), dynamic_cast(_to)); } solAssert(_to.category() == Type::Category::Array); @@ -3224,7 +3224,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) solAssert( fromType.arrayType().isImplicitlyConvertibleTo(targetType) || - (fromType.arrayType().isByteArray() && targetType.isByteArray()) + (fromType.arrayType().isByteArrayOrString() && targetType.isByteArrayOrString()) ); solAssert( fromType.arrayType().dataStoredIn(DataLocation::CallData) && @@ -3256,7 +3256,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) auto const& fromArrayType = dynamic_cast(_from); if (_to.category() == Type::Category::FixedBytes) { - solAssert(fromArrayType.isByteArray(), "Array types other than bytes not convertible to bytesNN."); + solAssert(fromArrayType.isByteArrayOrString(), "Array types other than bytes not convertible to bytesNN."); return bytesToFixedBytesConversionFunction(fromArrayType, dynamic_cast(_to)); } solAssert(_to.category() == Type::Category::Array, ""); @@ -3460,7 +3460,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) string YulUtilFunctions::bytesToFixedBytesConversionFunction(ArrayType const& _from, FixedBytesType const& _to) { - solAssert(_from.isByteArray() && !_from.isString(), ""); + solAssert(_from.isByteArrayOrString() && !_from.isString(), ""); solAssert(_from.isDynamicallySized(), ""); string functionName = "convert_bytes_to_fixedbytes_from_" + _from.identifier() + "_to_" + _to.identifier(); return m_functionCollector.createFunction(functionName, [&](auto& _args, auto& _returnParams) { @@ -3633,14 +3633,14 @@ string YulUtilFunctions::arrayConversionFunction(ArrayType const& _from, ArrayTy { if (_to.dataStoredIn(DataLocation::CallData)) solAssert( - _from.dataStoredIn(DataLocation::CallData) && _from.isByteArray() && _to.isByteArray(), + _from.dataStoredIn(DataLocation::CallData) && _from.isByteArrayOrString() && _to.isByteArrayOrString(), "" ); // Other cases are done explicitly in LValue::storeValue, and only possible by assignment. if (_to.location() == DataLocation::Storage) solAssert( - (_to.isPointer() || (_from.isByteArray() && _to.isByteArray())) && + (_to.isPointer() || (_from.isByteArrayOrString() && _to.isByteArrayOrString())) && _from.location() == DataLocation::Storage, "Invalid conversion to storage type." ); @@ -4238,7 +4238,7 @@ string YulUtilFunctions::conversionFunctionSpecial(Type const& _from, Type const } else if (_to.category() == Type::Category::Array) { - solAssert(dynamic_cast(_to).isByteArray(), ""); + solAssert(dynamic_cast(_to).isByteArrayOrString(), ""); Whiskers templ(R"( function () -> converted { converted := () diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index c2bb0c3cf3..e361ada473 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -677,7 +677,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) continue; if ( auto const* arrayType = dynamic_cast(returnTypes[i]); - arrayType && !arrayType->isByteArray() + arrayType && !arrayType->isByteArrayOrString() ) continue; @@ -698,7 +698,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) solAssert(returnTypes.size() == 1, ""); auto const* arrayType = dynamic_cast(returnTypes.front()); if (arrayType) - solAssert(arrayType->isByteArray(), ""); + solAssert(arrayType->isByteArrayOrString(), ""); vector retVars = IRVariable("ret", *returnTypes.front()).stackSlots(); returnVariables += retVars; code += Whiskers(R"( diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 86d00dbc9c..065b351f61 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -2088,7 +2088,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) else if (dynamic_cast(&actualType)) solAssert(member == "wrap" || member == "unwrap"); else if (auto const* arrayType = dynamic_cast(&actualType)) - solAssert(arrayType->isByteArray() && member == "concat"); + solAssert(arrayType->isByteArrayOrString() && member == "concat"); else // The old code generator had a generic "else" case here // without any specific code being generated, @@ -2226,7 +2226,7 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) setLValue(_indexAccess, IRLValue{ *arrayType.baseType(), - IRLValue::Memory{memAddress, arrayType.isByteArray()} + IRLValue::Memory{memAddress, arrayType.isByteArrayOrString()} }); break; } @@ -2240,7 +2240,7 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) ", " + expressionAsType(*_indexAccess.indexExpression(), *TypeProvider::uint256()) + ")"; - if (arrayType.isByteArray()) + if (arrayType.isByteArrayOrString()) define(_indexAccess) << m_utils.cleanupFunction(*arrayType.baseType()) << "(calldataload(" << diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index b42e9b3557..76342ba08e 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -953,7 +953,7 @@ bool isReturnedFromStructGetter(Type const* _type) if (category == Type::Category::Mapping) return false; if (category == Type::Category::Array) - return dynamic_cast(*_type).isByteArray(); + return dynamic_cast(*_type).isByteArrayOrString(); // default return true; } @@ -990,7 +990,7 @@ void SMTEncoder::visitPublicGetter(FunctionCall const& _funCall) { if ( type->isValueType() || - (type->category() == Type::Category::Array && dynamic_cast(*type).isByteArray()) + (type->category() == Type::Category::Array && dynamic_cast(*type).isByteArrayOrString()) ) { solAssert(symbArguments.empty(), ""); @@ -1071,7 +1071,7 @@ void SMTEncoder::visitTypeConversion(FunctionCall const& _funCall) if (auto sliceType = dynamic_cast(argType)) arrayType = &sliceType->arrayType(); - if (arrayType && arrayType->isByteArray() && smt::isFixedBytes(*funCallType)) + if (arrayType && arrayType->isByteArrayOrString() && smt::isFixedBytes(*funCallType)) { auto array = dynamic_pointer_cast(m_context.expression(*argument)); bytesToFixedBytesAssertions(*array, _funCall); @@ -2695,14 +2695,14 @@ Expression const* SMTEncoder::cleanExpression(Expression const& _expr) auto typeType = dynamic_cast(functionCall->expression().annotation().type); solAssert(typeType, ""); if (auto const* arrayType = dynamic_cast(typeType->actualType())) - if (arrayType->isByteArray()) + if (arrayType->isByteArrayOrString()) { // this is a cast to `bytes` solAssert(functionCall->arguments().size() == 1, ""); Expression const& arg = *functionCall->arguments()[0]; if ( auto const* argArrayType = dynamic_cast(arg.annotation().type); - argArrayType && argArrayType->isByteArray() + argArrayType && argArrayType->isByteArrayOrString() ) return cleanExpression(arg); } diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 36d9a0f353..024e33be6e 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -96,7 +96,7 @@ SortPointer smtSort(frontend::Type const& _type) auto sliceArrayType = dynamic_cast(&_type); ArrayType const* arrayType = sliceArrayType ? &sliceArrayType->arrayType() : dynamic_cast(&_type); if ( - (arrayType && (arrayType->isString() || arrayType->isByteArray())) || + (arrayType && (arrayType->isString() || arrayType->isByteArrayOrString())) || _type.category() == frontend::Type::Category::StringLiteral ) tupleName = "bytes"; diff --git a/libsolidity/interface/ABI.cpp b/libsolidity/interface/ABI.cpp index cf395ffa02..9c7a645b6f 100644 --- a/libsolidity/interface/ABI.cpp +++ b/libsolidity/interface/ABI.cpp @@ -176,7 +176,7 @@ Json::Value ABI::formatType( ret["type"] = _encodingType.canonicalName() + suffix; else if (ArrayType const* arrayType = dynamic_cast(&_encodingType)) { - if (arrayType->isByteArray()) + if (arrayType->isByteArrayOrString()) ret["type"] = _encodingType.canonicalName() + suffix; else { diff --git a/libsolidity/interface/StorageLayout.cpp b/libsolidity/interface/StorageLayout.cpp index a484503c11..74d7ccf4bb 100644 --- a/libsolidity/interface/StorageLayout.cpp +++ b/libsolidity/interface/StorageLayout.cpp @@ -94,7 +94,7 @@ void StorageLayout::generate(Type const* _type) } else if (auto arrayType = dynamic_cast(_type)) { - if (arrayType->isByteArray()) + if (arrayType->isByteArrayOrString()) typeInfo["encoding"] = "bytes"; else { From cc6344c03c2b9c00a76bc2af1d9f1da7aa9c467b Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Wed, 2 Feb 2022 16:14:24 +0530 Subject: [PATCH 0337/1748] Changed instaces of isByteArrayOrString() to isByteArray() where it's only supposed to return a True for Bytes Type --- libsolidity/analysis/TypeChecker.cpp | 2 +- libsolidity/ast/Types.cpp | 6 +++--- libsolidity/ast/Types.h | 2 ++ libsolidity/codegen/CompilerUtils.cpp | 4 ++-- libsolidity/codegen/YulUtilFunctions.cpp | 6 +++--- libsolidity/formal/SymbolicTypes.cpp | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 1a07d6ded0..5b03717d9d 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1791,7 +1791,7 @@ Type const* TypeChecker::typeCheckTypeConversionAndRetrieveReturnType( ); else solAssert( - argArrayType->isByteArrayOrString() && !argArrayType->isString() && resultType->category() == Type::Category::FixedBytes, + argArrayType->isByteArray() && resultType->category() == Type::Category::FixedBytes, "" ); } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index f50210ff55..74cd76ee73 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1530,7 +1530,7 @@ BoolResult ArrayType::isImplicitlyConvertibleTo(Type const& _convertTo) const if (_convertTo.category() != category()) return false; auto& convertTo = dynamic_cast(_convertTo); - if (convertTo.isByteArrayOrString() != isByteArrayOrString() || convertTo.isString() != isString()) + if (convertTo.isByteArray() != isByteArray() || convertTo.isString() != isString()) return false; // memory/calldata to storage can be converted, but only to a direct storage reference if (convertTo.location() == DataLocation::Storage && location() != DataLocation::Storage && convertTo.isPointer()) @@ -1571,7 +1571,7 @@ BoolResult ArrayType::isExplicitlyConvertibleTo(Type const& _convertTo) const return true; // allow conversion bytes <-> string and bytes -> bytesNN if (_convertTo.category() != category()) - return isByteArrayOrString() && !isString() && _convertTo.category() == Type::Category::FixedBytes; + return isByteArray() && _convertTo.category() == Type::Category::FixedBytes; auto& convertTo = dynamic_cast(_convertTo); if (convertTo.location() != location()) return false; @@ -1608,7 +1608,7 @@ bool ArrayType::operator==(Type const& _other) const ArrayType const& other = dynamic_cast(_other); if ( !ReferenceType::operator==(other) || - other.isByteArrayOrString() != isByteArrayOrString() || + other.isByteArray() != isByteArray() || other.isString() != isString() || other.isDynamicallySized() != isDynamicallySized() ) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index e34c114057..3f134df17d 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -837,6 +837,8 @@ class ArrayType: public ReferenceType BoolResult validForLocation(DataLocation _loc) const override; + /// @returns true if this is a byte array. + bool isByteArray() const { return m_arrayKind == ArrayKind::Bytes; } /// @returns true if this is a byte array or a string bool isByteArrayOrString() const { return m_arrayKind != ArrayKind::Ordinary; } /// @returns true if this is a string diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index ba678878f2..0ad37241b4 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -992,7 +992,7 @@ void CompilerUtils::convertType( if (_targetType.category() == Type::Category::FixedBytes) { solAssert( - typeOnStack.isByteArrayOrString() && !typeOnStack.isString(), + typeOnStack.isByteArray(), "Array types other than bytes not convertible to bytesNN." ); solAssert(typeOnStack.isDynamicallySized()); @@ -1119,7 +1119,7 @@ void CompilerUtils::convertType( if (_targetType.category() == Type::Category::FixedBytes) { solAssert( - typeOnStack.arrayType().isByteArrayOrString() && !typeOnStack.arrayType().isString(), + typeOnStack.arrayType().isByteArray(), "Array types other than bytes not convertible to bytesNN." ); solAssert(typeOnStack.isDynamicallySized()); diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 3c79b64b46..9b50d68cd9 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -3216,7 +3216,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) auto const& fromType = dynamic_cast(_from); if (_to.category() == Type::Category::FixedBytes) { - solAssert(fromType.arrayType().isByteArrayOrString(), "Array types other than bytes not convertible to bytesNN."); + solAssert(fromType.arrayType().isByteArray(), "Array types other than bytes not convertible to bytesNN."); return bytesToFixedBytesConversionFunction(fromType.arrayType(), dynamic_cast(_to)); } solAssert(_to.category() == Type::Category::Array); @@ -3256,7 +3256,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) auto const& fromArrayType = dynamic_cast(_from); if (_to.category() == Type::Category::FixedBytes) { - solAssert(fromArrayType.isByteArrayOrString(), "Array types other than bytes not convertible to bytesNN."); + solAssert(fromArrayType.isByteArray(), "Array types other than bytes not convertible to bytesNN."); return bytesToFixedBytesConversionFunction(fromArrayType, dynamic_cast(_to)); } solAssert(_to.category() == Type::Category::Array, ""); @@ -3460,7 +3460,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) string YulUtilFunctions::bytesToFixedBytesConversionFunction(ArrayType const& _from, FixedBytesType const& _to) { - solAssert(_from.isByteArrayOrString() && !_from.isString(), ""); + solAssert(_from.isByteArray(), ""); solAssert(_from.isDynamicallySized(), ""); string functionName = "convert_bytes_to_fixedbytes_from_" + _from.identifier() + "_to_" + _to.identifier(); return m_functionCollector.createFunction(functionName, [&](auto& _args, auto& _returnParams) { diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp index 024e33be6e..b9041c6bd4 100644 --- a/libsolidity/formal/SymbolicTypes.cpp +++ b/libsolidity/formal/SymbolicTypes.cpp @@ -96,7 +96,7 @@ SortPointer smtSort(frontend::Type const& _type) auto sliceArrayType = dynamic_cast(&_type); ArrayType const* arrayType = sliceArrayType ? &sliceArrayType->arrayType() : dynamic_cast(&_type); if ( - (arrayType && (arrayType->isString() || arrayType->isByteArrayOrString())) || + (arrayType && arrayType->isByteArrayOrString()) || _type.category() == frontend::Type::Category::StringLiteral ) tupleName = "bytes"; From dcaa094f1f3850203f3908b9853efefeb3c54d58 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 2 Feb 2022 18:11:14 -0500 Subject: [PATCH 0338/1748] Add NatSpec note for libraries --- 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 297bbc8c62..a66c104629 100644 --- a/docs/natspec-format.rst +++ b/docs/natspec-format.rst @@ -36,7 +36,7 @@ tools. Documentation Example ===================== -Documentation is inserted above each ``contract``, ``interface``, +Documentation is inserted above each ``contract``, ``interface``, ``library``, ``function``, and ``event`` using the Doxygen notation format. A ``public`` state variable is equivalent to a ``function`` for the purposes of NatSpec. From f5b345504beab1f1cd10c21f382f97b7c6aa5321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 3 Feb 2022 14:52:58 +0100 Subject: [PATCH 0339/1748] When installing solc-js use the dist/ subdir, which contains the built JS files --- scripts/bytecodecompare/storebytecode.sh | 2 +- scripts/solc-bin/bytecode_reports_for_modified_binaries.sh | 4 ++-- test/externalTests/colony.sh | 6 +++--- test/externalTests/gnosis-v2.sh | 6 +++--- test/externalTests/gnosis.sh | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/scripts/bytecodecompare/storebytecode.sh b/scripts/bytecodecompare/storebytecode.sh index 1c300662bc..3574fe6bfb 100755 --- a/scripts/bytecodecompare/storebytecode.sh +++ b/scripts/bytecodecompare/storebytecode.sh @@ -52,7 +52,7 @@ TMPDIR=$(mktemp -d) popd cp "$REPO_ROOT/scripts/bytecodecompare/prepare_report.js" . - npm install solc-js/ + npm install ./solc-js/dist echo "Running the compiler..." # shellcheck disable=SC2035 diff --git a/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh b/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh index be151bca86..68ab995afc 100755 --- a/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh +++ b/scripts/solc-bin/bytecode_reports_for_modified_binaries.sh @@ -149,11 +149,11 @@ for binary_name in $platform_binaries; do if [[ $platform == emscripten-wasm32 ]] || [[ $platform == emscripten-asmjs ]]; then ln -sf "${solc_bin_dir}/${platform}/${binary_name}" "${solcjs_dir}/soljson.js" ln -sf "${solc_bin_dir}/${platform}/${binary_name}" "${solcjs_dir}/dist/soljson.js" - ln -s "${solcjs_dir}" solc-js + npm install "${solcjs_dir}/dist" cp "${script_dir}/bytecodecompare/prepare_report.js" prepare_report.js validate_reported_version \ - "$(solc-js/dist/solc.js --version)" \ + "$(node_modules/solc/solc.js --version)" \ "$solidity_version_and_commit" # shellcheck disable=SC2035 diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 8386b0b491..d659899535 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -59,7 +59,7 @@ function colony_test [[ $BINARY_TYPE == native ]] && replace_global_solc "$BINARY_PATH" neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$(first_word "$SELECTED_PRESETS")" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$(first_word "$SELECTED_PRESETS")" yarn install git submodule update --init @@ -69,10 +69,10 @@ function colony_test cd .. replace_version_pragmas - [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" + [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc/dist" for preset in $SELECTED_PRESETS; do - truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$preset" "${compile_only_presets[*]}" compile_fn test_fn + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$preset" "${compile_only_presets[*]}" compile_fn test_fn done } diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 16f3d6f622..8ad070d113 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -63,14 +63,14 @@ function gnosis_safe_test neutralize_package_lock neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$(first_word "$SELECTED_PRESETS")" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$(first_word "$SELECTED_PRESETS")" npm install --package-lock replace_version_pragmas - [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" + [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc/dist" for preset in $SELECTED_PRESETS; do - truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$preset" "${compile_only_presets[*]}" compile_fn test_fn + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$preset" "${compile_only_presets[*]}" compile_fn test_fn done } diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 62dea10df6..edada2fef3 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -61,14 +61,14 @@ function gnosis_safe_test neutralize_package_lock neutralize_package_json_hooks - force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$(first_word "$SELECTED_PRESETS")" + force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$(first_word "$SELECTED_PRESETS")" npm install --package-lock replace_version_pragmas - [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc" + [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc/dist" for preset in $SELECTED_PRESETS; do - truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc" "$preset" "${compile_only_presets[*]}" compile_fn test_fn + truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$preset" "${compile_only_presets[*]}" compile_fn test_fn done } From e85bceb4178f82e05762dc3e7e7bcf3020ded091 Mon Sep 17 00:00:00 2001 From: nishant-sachdeva Date: Fri, 4 Feb 2022 02:08:36 +0530 Subject: [PATCH 0340/1748] Types.h:872 had a comment /// String is interpreted as a subtype of Bytes. - this was now incorrect after #12593 . That has been removed now. --- libsolidity/ast/Types.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 3f134df17d..c4aaf38ca1 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -864,7 +864,6 @@ class ArrayType: public ReferenceType std::vector decomposition() const override { return {m_baseType}; } private: - /// String is interpreted as a subtype of Bytes. enum class ArrayKind { Ordinary, Bytes, String }; bigint unlimitedStaticCalldataSize(bool _padded) const; From b925250705d5ba44cbf6a2b49bb78eacaa402d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 28 Jan 2022 19:14:29 +0100 Subject: [PATCH 0341/1748] Make solc-js.sh run its tests directly - Its structure has diverged a lot from other external tests and there's not point in keeping it abstracted like this. --- test/externalTests/common.sh | 14 -------------- test/externalTests/solc-js/solc-js.sh | 8 ++++---- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 10df975256..3737069cb3 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -323,20 +323,6 @@ function hardhat_clean rm -rf artifacts/ cache/ } -function run_test -{ - local compile_fn="$1" - local test_fn="$2" - - replace_version_pragmas - - printLog "Running compile function..." - time $compile_fn - - printLog "Running test function..." - $test_fn -} - function settings_from_preset { local preset="$1" diff --git a/test/externalTests/solc-js/solc-js.sh b/test/externalTests/solc-js/solc-js.sh index 33b43e6430..3da03519b3 100755 --- a/test/externalTests/solc-js/solc-js.sh +++ b/test/externalTests/solc-js/solc-js.sh @@ -29,9 +29,6 @@ VERSION="$2" [[ $SOLJSON != "" && -f "$SOLJSON" && $VERSION != "" ]] || fail "Usage: $0 " -function compile_fn { echo "Nothing to compile."; } -function test_fn { npm test; } - function solcjs_test { TEST_DIR=$(pwd) @@ -60,7 +57,10 @@ function solcjs_test echo "Updating package.json to version $VERSION" npm version --allow-same-version --no-git-tag-version "$VERSION" - run_test compile_fn test_fn + replace_version_pragmas + + printLog "Running test function..." + npm test } external_test solc-js solcjs_test From 9e641e60e7eeff966f3cd33824cf42bdb5111493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 28 Jan 2022 20:51:04 +0100 Subject: [PATCH 0342/1748] externalTests/solc-js: Allow using a local checkout of solc-js --- test/externalTests/common.sh | 10 +++++++++- test/externalTests/solc-js/solc-js.sh | 5 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 3737069cb3..ec782f0562 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -71,15 +71,23 @@ function setup_solc local binary_path="$3" local solcjs_branch="${4:-master}" local install_dir="${5:-solc/}" + local solcjs_dir="$6" [[ $binary_type == native || $binary_type == solcjs ]] || assertFail + [[ $binary_type == solcjs || $solcjs_dir == "" ]] || assertFail cd "$test_dir" if [[ $binary_type == solcjs ]] then printLog "Setting up solc-js..." - git clone --depth 1 -b "$solcjs_branch" https://github.com/ethereum/solc-js.git "$install_dir" + if [[ $solcjs_dir == "" ]]; then + printLog "Cloning branch ${solcjs_branch}..." + git clone --depth 1 -b "$solcjs_branch" https://github.com/ethereum/solc-js.git "$install_dir" + else + printLog "Using local solc-js from ${solcjs_dir}..." + cp -ra "$solcjs_dir" solc + fi pushd "$install_dir" npm install diff --git a/test/externalTests/solc-js/solc-js.sh b/test/externalTests/solc-js/solc-js.sh index 3da03519b3..bf7ca87628 100755 --- a/test/externalTests/solc-js/solc-js.sh +++ b/test/externalTests/solc-js/solc-js.sh @@ -26,8 +26,9 @@ source test/externalTests/common.sh SOLJSON="$1" VERSION="$2" +SOLCJS_CHECKOUT="$3" # optional -[[ $SOLJSON != "" && -f "$SOLJSON" && $VERSION != "" ]] || fail "Usage: $0 " +[[ $SOLJSON != "" && -f "$SOLJSON" && $VERSION != "" ]] || fail "Usage: $0 []" function solcjs_test { @@ -35,7 +36,7 @@ function solcjs_test SOLCJS_INPUT_DIR="$TEST_DIR"/test/externalTests/solc-js # set up solc-js on the branch specified - setup_solc "$DIR" solcjs "$SOLJSON" master solc/ + setup_solc "$DIR" solcjs "$SOLJSON" master solc/ "$SOLCJS_CHECKOUT" cd solc/ printLog "Updating index.js file..." From b52032a452004e53115a8c214341593ef29018db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 4 Feb 2022 15:18:37 +0100 Subject: [PATCH 0343/1748] Re-enable Bleeps and just disable the failing governor test --- .circleci/config.yml | 3 +-- test/externalTests/bleeps.sh | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 44b44bb012..143a692fdb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1468,8 +1468,7 @@ workflows: - t_ems_ext: *job_native_test_ext_trident - t_ems_ext: *job_native_test_ext_euler - t_ems_ext: *job_native_test_ext_yield_liquidator - # Disabled until we have a fix for https://github.com/wighawag/bleeps/issues/2 - #-t_ems_ext: *job_native_test_ext_bleeps + - t_ems_ext: *job_native_test_ext_bleeps - t_ems_ext: *job_native_test_ext_pool_together - t_ems_ext: *job_native_test_ext_perpetual_pools - t_ems_ext: *job_native_test_ext_uniswap diff --git a/test/externalTests/bleeps.sh b/test/externalTests/bleeps.sh index d005cf8efb..561200e219 100755 --- a/test/externalTests/bleeps.sh +++ b/test/externalTests/bleeps.sh @@ -72,6 +72,10 @@ function bleeps_test sed -i 's/msg\.sender\.transfer(/payable(msg.sender).transfer(/g' src/externals/WETH9.sol sed -i 's/^\s*\(Deposit\|Withdrawal\|Approval\|Transfer\)(/emit \1(/g' src/externals/WETH9.sol + # This test does not currently pass due to an upstream problem. + # TODO: Remove this line when https://github.com/wighawag/bleeps/issues/2 is fixed + rm test/BleepsDAO.governor.test.ts + neutralize_package_lock neutralize_package_json_hooks force_hardhat_compiler_binary "$config_file" "$BINARY_TYPE" "$BINARY_PATH" From 4ebd839d3a303814865b83ff2c605f1a50d80b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 4 Feb 2022 15:51:34 +0100 Subject: [PATCH 0344/1748] Run full tests, not just test:contracts in PRBMath external test - `test:contracts` does not seem to be running any tests at all. --- test/externalTests/prb-math.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/prb-math.sh b/test/externalTests/prb-math.sh index 339a5e75d4..53fad2c255 100755 --- a/test/externalTests/prb-math.sh +++ b/test/externalTests/prb-math.sh @@ -30,7 +30,7 @@ BINARY_PATH="$2" SELECTED_PRESETS="$3" function compile_fn { yarn compile; } -function test_fn { yarn test:contracts; } +function test_fn { yarn test; } function prb_math_test { From 653c1e68429937abec17c9242a191227db0202b9 Mon Sep 17 00:00:00 2001 From: Ayush Shukla Date: Thu, 3 Feb 2022 20:26:46 +0530 Subject: [PATCH 0345/1748] Fix slot calculation for bytes/string mapping --- docs/internals/layout_in_storage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/internals/layout_in_storage.rst b/docs/internals/layout_in_storage.rst index b1b89a6a3c..9afe97ddbf 100644 --- a/docs/internals/layout_in_storage.rst +++ b/docs/internals/layout_in_storage.rst @@ -90,7 +90,7 @@ The value corresponding to a mapping key ``k`` is located at ``keccak256(h(k) . where ``.`` is concatenation and ``h`` is a function that is applied to the key depending on its type: - for value types, ``h`` pads the value to 32 bytes in the same way as when storing the value in memory. -- for strings and byte arrays, ``h`` computes the ``keccak256`` hash of the unpadded data. +- for strings and byte arrays, ``h(k)`` is just the unpadded data. If the mapping value is a non-value type, the computed slot marks the start of the data. If the value is of struct type, From 4d65bfa95e28f3dc3b8ad6cd6aaf8578c15851c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 5 Feb 2022 00:05:39 +0100 Subject: [PATCH 0346/1748] CI: Remove notes about Hardhat failing on nodejs 17; that version is officially not supported --- .circleci/config.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 143a692fdb..3f2c661a0c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -521,35 +521,30 @@ defaults: name: t_native_test_ext_ens project: ens binary_type: native - # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' - job_native_test_ext_trident: &job_native_test_ext_trident <<: *workflow_ubuntu2004_static name: t_native_test_ext_trident project: trident binary_type: native - # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' - job_native_test_ext_euler: &job_native_test_ext_euler <<: *workflow_ubuntu2004_static name: t_native_test_ext_euler project: euler binary_type: native - # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' - job_native_test_ext_yield_liquidator: &job_native_test_ext_yield_liquidator <<: *workflow_ubuntu2004_static name: t_native_test_ext_yield_liquidator project: yield-liquidator binary_type: native - # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' - job_native_test_ext_bleeps: &job_native_test_ext_bleeps <<: *workflow_ubuntu2004_static name: t_native_test_ext_bleeps project: bleeps binary_type: native - # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' resource_class: medium - job_native_test_ext_pool_together: &job_native_test_ext_pool_together @@ -557,35 +552,30 @@ defaults: name: t_native_test_ext_pool_together project: pool-together binary_type: native - # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' - job_native_test_ext_perpetual_pools: &job_native_test_ext_perpetual_pools <<: *workflow_ubuntu2004_static name: t_native_test_ext_perpetual_pools project: perpetual-pools binary_type: native - # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' - job_native_test_ext_uniswap: &job_native_test_ext_uniswap <<: *workflow_ubuntu2004_static name: t_native_test_ext_uniswap project: uniswap binary_type: native - # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' - job_native_test_prb_math: &job_native_test_prb_math <<: *workflow_ubuntu2004_static name: t_native_test_ext_prb_math project: prb-math binary_type: native - # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' - job_native_test_ext_elementfi: &job_native_test_ext_elementfi <<: *workflow_ubuntu2004_static name: t_native_test_ext_elementfi project: elementfi binary_type: native - # NOTE: Tests crash on nodejs 17: "Error: error:0308010C:digital envelope routines::unsupported" nodejs_version: '16' resource_class: medium - job_ems_test_ext_colony: &job_ems_test_ext_colony From 247eab90567e36fb9d8e390ef530551316fc7a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 5 Feb 2022 00:03:53 +0100 Subject: [PATCH 0347/1748] CI: Rename node_latest_small to node_small --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3f2c661a0c..db9baaa642 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -384,7 +384,7 @@ defaults: TERM: xterm MAKEFLAGS: -j 2 - - base_node_latest_small: &base_node_latest_small + - base_node_small: &base_node_small docker: - image: circleci/node resource_class: small @@ -605,7 +605,7 @@ jobs: - gitter_notify_failure_unless_pr chk_docs_examples: - <<: *base_node_latest_small + <<: *base_node_small steps: - checkout - attach_workspace: @@ -674,7 +674,7 @@ jobs: - gitter_notify_failure_unless_pr chk_buglist: - <<: *base_node_latest_small + <<: *base_node_small steps: - checkout - run: @@ -1136,7 +1136,7 @@ jobs: - gitter_notify_failure_unless_pr t_ems_ext_hardhat: - <<: *base_node_latest_small + <<: *base_node_small environment: TERM: xterm HARDHAT_TESTS_SOLC_PATH: /tmp/workspace/soljson.js @@ -1339,7 +1339,7 @@ jobs: - gitter_notify_failure_unless_pr b_bytecode_ems: - <<: *base_node_latest_small + <<: *base_node_small environment: SOLC_EMSCRIPTEN: "On" steps: From 2f0ccb21bef0ddee12b37b52289ca7081b6a5d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 5 Feb 2022 00:04:20 +0100 Subject: [PATCH 0348/1748] CI: Switch t_ems_ext_hardhat to nodejs 16 --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index db9baaa642..58a4c27428 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1137,6 +1137,8 @@ jobs: t_ems_ext_hardhat: <<: *base_node_small + docker: + - image: circleci/node:16 environment: TERM: xterm HARDHAT_TESTS_SOLC_PATH: /tmp/workspace/soljson.js From 7634fc4ea9537d60fdf686f43a4e54e7ab0f43fe Mon Sep 17 00:00:00 2001 From: a3d4 Date: Fri, 4 Feb 2022 17:54:21 +0100 Subject: [PATCH 0349/1748] Clarify symlink handling on Windows --- docs/contributing.rst | 7 +++++++ test/FilesystemUtils.cpp | 1 + 2 files changed, 8 insertions(+) diff --git a/docs/contributing.rst b/docs/contributing.rst index 2895744ef4..ba5a0a0f8f 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -94,6 +94,13 @@ dependencies (`evmone `_, On macOS some of the testing scripts expect GNU coreutils to be installed. This can be easiest accomplished using Homebrew: ``brew install coreutils``. +On Windows systems make sure that you have a privilege to create symlinks, +otherwise several tests may fail. +Administrators should have that privilege, but you may also +`grant it to other users `_ +or +`enable Developer Mode `_. + Running the Tests ----------------- diff --git a/test/FilesystemUtils.cpp b/test/FilesystemUtils.cpp index 0235b11476..0d1de3af95 100644 --- a/test/FilesystemUtils.cpp +++ b/test/FilesystemUtils.cpp @@ -81,5 +81,6 @@ bool solidity::test::createSymlinkIfSupportedByFilesystem( BOOST_THROW_EXCEPTION(runtime_error( "Failed to create a symbolic link: \"" + _linkName.string() + "\"" " -> " + _targetPath.string() + "\"." + " " + symlinkCreationError.message() + "." )); } From 0a17495cf94016318ee76f299419595d6bfdd718 Mon Sep 17 00:00:00 2001 From: a3d4 Date: Sat, 5 Feb 2022 11:51:11 +0100 Subject: [PATCH 0350/1748] Treat root path in normalizeCLIPathForVFS as case insensitive on Windows --- libsolidity/interface/FileReader.cpp | 3 ++- test/libsolidity/interface/FileReader.cpp | 28 +++++++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/libsolidity/interface/FileReader.cpp b/libsolidity/interface/FileReader.cpp index 47f4d2b5aa..adb4b01cae 100644 --- a/libsolidity/interface/FileReader.cpp +++ b/libsolidity/interface/FileReader.cpp @@ -269,7 +269,8 @@ boost::filesystem::path FileReader::normalizeCLIPathForVFS( if (!isUNCPath(normalizedPath)) { boost::filesystem::path workingDirRootPath = canonicalWorkDir.root_path(); - if (normalizedRootPath == workingDirRootPath) + // Ignore drive letter case on Windows (C:\ <=> c:\). + if (boost::filesystem::equivalent(normalizedRootPath, workingDirRootPath)) normalizedRootPath = "/"; } diff --git a/test/libsolidity/interface/FileReader.cpp b/test/libsolidity/interface/FileReader.cpp index 866a4435ac..39355e536f 100644 --- a/test/libsolidity/interface/FileReader.cpp +++ b/test/libsolidity/interface/FileReader.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -192,8 +193,8 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_root_name_only) #if defined(_WIN32) boost::filesystem::path driveLetter = boost::filesystem::current_path().root_name(); - solAssert(!driveLetter.empty(), ""); - solAssert(driveLetter.is_relative(), ""); + soltestAssert(!driveLetter.empty(), ""); + soltestAssert(driveLetter.is_relative(), ""); BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(driveLetter, resolveSymlinks), expectedWorkDir); #endif @@ -212,13 +213,32 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_stripping_root_name) for (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled}) { + boost::filesystem::path workDir = boost::filesystem::current_path(); + boost::filesystem::path normalizedPath = FileReader::normalizeCLIPathForVFS( - boost::filesystem::current_path(), + workDir, resolveSymlinks ); - BOOST_CHECK_EQUAL(normalizedPath, "/" / boost::filesystem::current_path().relative_path()); + BOOST_CHECK_EQUAL(normalizedPath, "/" / workDir.relative_path()); BOOST_TEST(normalizedPath.root_name().empty()); BOOST_CHECK_EQUAL(normalizedPath.root_directory(), "/"); + +#if defined(_WIN32) + string root = workDir.root_path().string(); + soltestAssert(root.length() == 3 && root[1] == ':' && root[2] == '\\', ""); + + for (auto convert: {boost::to_lower_copy, boost::to_upper_copy}) + { + boost::filesystem::path workDirWin = convert(root, locale()) / workDir.relative_path(); + normalizedPath = FileReader::normalizeCLIPathForVFS( + workDirWin, + resolveSymlinks + ); + BOOST_CHECK_EQUAL(normalizedPath, "/" / workDir.relative_path()); + BOOST_TEST(normalizedPath.root_name().empty()); + BOOST_CHECK_EQUAL(normalizedPath.root_directory(), "/"); + } +#endif } } From a0dd2cd1ff59d06425c78180a2a8a6e2c8ff506e Mon Sep 17 00:00:00 2001 From: a3d4 Date: Sat, 5 Feb 2022 15:12:49 +0100 Subject: [PATCH 0351/1748] Remove a reference to unused SolidityFixedFeeRegistrar --- test/boostTest.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/boostTest.cpp b/test/boostTest.cpp index bfb546736c..1cc512c325 100644 --- a/test/boostTest.cpp +++ b/test/boostTest.cpp @@ -57,7 +57,7 @@ void removeTestSuite(std::string const& _name) { master_test_suite_t& master = framework::master_test_suite(); auto id = master.get(_name); - assert(id != INV_TEST_UNIT_ID); + soltestAssert(id != INV_TEST_UNIT_ID, "Removing non-existent test suite!"); master.remove(id); } @@ -279,7 +279,6 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) "ABIDecoderTest", "ABIEncoderTest", "SolidityAuctionRegistrar", - "SolidityFixedFeeRegistrar", "SolidityWallet", "GasMeterTests", "GasCostTests", From 6bd38aa4ef2ca036775896b77909b361ed3d8855 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Sat, 5 Feb 2022 23:59:09 -0500 Subject: [PATCH 0352/1748] Fix signature of pop member --- docs/types/reference-types.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/types/reference-types.rst b/docs/types/reference-types.rst index 126440321c..88e23a47eb 100644 --- a/docs/types/reference-types.rst +++ b/docs/types/reference-types.rst @@ -337,9 +337,9 @@ Array Members Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``push(x)`` that you can use to append a given element at the end of the array. The function returns nothing. -**pop**: +**pop()**: Dynamic storage arrays and ``bytes`` (not ``string``) have a member - function called ``pop`` that you can use to remove an element from the + function called ``pop()`` that you can use to remove an element from the end of the array. This also implicitly calls :ref:`delete` on the removed element. .. note:: From c3145979fc18c104479379916b17364e94fccb16 Mon Sep 17 00:00:00 2001 From: Hakeem Almidan Date: Sun, 6 Feb 2022 20:16:04 +0300 Subject: [PATCH 0353/1748] Update cheatsheet.rst Add more description to the bullet point of 'block.timestamp' (under 'Global Variables') --- docs/cheatsheet.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index eab1e3d52a..cd9ba5c149 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -92,7 +92,7 @@ Global Variables - ``block.difficulty`` (``uint``): current block difficulty - ``block.gaslimit`` (``uint``): current block gaslimit - ``block.number`` (``uint``): current block number -- ``block.timestamp`` (``uint``): current block timestamp +- ``block.timestamp`` (``uint``): current block timestamp in seconds since Unix epoch - ``gasleft() returns (uint256)``: remaining gas - ``msg.data`` (``bytes``): complete calldata - ``msg.sender`` (``address``): sender of the message (current call) From 4715fafb829a156e25a027027d8632689ee3d04b Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 7 Feb 2022 11:31:59 +0100 Subject: [PATCH 0354/1748] Re-enable preset for poolTogether. --- test/externalTests/pool-together.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/pool-together.sh b/test/externalTests/pool-together.sh index 1cabd6a501..a7f5933c0e 100755 --- a/test/externalTests/pool-together.sh +++ b/test/externalTests/pool-together.sh @@ -45,7 +45,7 @@ function pool_together_test "${compile_only_presets[@]}" #ir-no-optimize # Compilation fails with "YulException: Variable var_amount_205 is 9 slot(s) too deep inside the stack." #ir-optimize-evm-only # Compilation fails with "YulException: Variable var_amount_205 is 9 slot(s) too deep inside the stack." - #ir-optimize-evm+yul # FIXME: ICE due to https://github.com/ethereum/solidity/issues/12558 + ir-optimize-evm+yul legacy-no-optimize legacy-optimize-evm-only legacy-optimize-evm+yul From b9fe628b70b0f118f02822ace678a69c39f5843c Mon Sep 17 00:00:00 2001 From: Marenz Date: Thu, 27 Jan 2022 14:07:50 +0100 Subject: [PATCH 0355/1748] Emit immutable references for pure yul code --- Changelog.md | 1 + libsolidity/interface/StandardCompiler.cpp | 22 ++++---- .../standard_yul_immutable_references/args | 1 + .../input.json | 22 ++++++++ .../output.json | 52 +++++++++++++++++++ .../standard_yul_object_name/output.json | 2 +- 6 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 test/cmdlineTests/standard_yul_immutable_references/args create mode 100644 test/cmdlineTests/standard_yul_immutable_references/input.json create mode 100644 test/cmdlineTests/standard_yul_immutable_references/output.json diff --git a/Changelog.md b/Changelog.md index e75e2c710e..c938c44b0f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Language Features: Compiler Features: * Yul Optimizer: Remove ``mstore`` and ``sstore`` operations if the slot already contains the same value. + * Yul: Emit immutable references for pure yul code when requested. diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 39ed7c10fb..5ccf2d447b 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1461,36 +1461,36 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) stack.optimize(); MachineAssemblyObject object; - MachineAssemblyObject runtimeObject; - tie(object, runtimeObject) = stack.assembleWithDeployed(); + MachineAssemblyObject deployedObject; + tie(object, deployedObject) = stack.assembleWithDeployed(); if (object.bytecode) object.bytecode->link(_inputsAndSettings.libraries); - if (runtimeObject.bytecode) - runtimeObject.bytecode->link(_inputsAndSettings.libraries); + if (deployedObject.bytecode) + deployedObject.bytecode->link(_inputsAndSettings.libraries); - for (string const& objectKind: vector{"bytecode", "deployedBytecode"}) + for (auto&& [kind, isDeployed]: {make_pair("bytecode"s, false), make_pair("deployedBytecode"s, true)}) if (isArtifactRequested( _inputsAndSettings.outputSelection, sourceName, contractName, - evmObjectComponents(objectKind), + evmObjectComponents(kind), wildcardMatchesExperimental )) { - MachineAssemblyObject const& o = objectKind == "bytecode" ? object : runtimeObject; + MachineAssemblyObject const& o = isDeployed ? deployedObject : object; if (o.bytecode) - output["contracts"][sourceName][contractName]["evm"][objectKind] = + output["contracts"][sourceName][contractName]["evm"][kind] = collectEVMObject( *o.bytecode, o.sourceMappings.get(), Json::arrayValue, - false, - [&](string const& _element) { return isArtifactRequested( + isDeployed, + [&, kind = kind](string const& _element) { return isArtifactRequested( _inputsAndSettings.outputSelection, sourceName, contractName, - "evm." + objectKind + "." + _element, + "evm." + kind + "." + _element, wildcardMatchesExperimental ); } ); diff --git a/test/cmdlineTests/standard_yul_immutable_references/args b/test/cmdlineTests/standard_yul_immutable_references/args new file mode 100644 index 0000000000..d13a8ac44a --- /dev/null +++ b/test/cmdlineTests/standard_yul_immutable_references/args @@ -0,0 +1 @@ +--pretty-json diff --git a/test/cmdlineTests/standard_yul_immutable_references/input.json b/test/cmdlineTests/standard_yul_immutable_references/input.json new file mode 100644 index 0000000000..aedbae8683 --- /dev/null +++ b/test/cmdlineTests/standard_yul_immutable_references/input.json @@ -0,0 +1,22 @@ +{ + "language": "Yul", + "sources": + { + "A": + { + "content": "object \"YulTest\" { code { let size := datasize(\"runtime\") datacopy(0, dataoffset(\"runtime\"), size) setimmutable(0, \"test\", 1) return(0, size) } object \"runtime\" { code { mstore(0, loadimmutable(\"test\")) return(0, 0x20) } }}" + } + }, + "settings": + { + "outputSelection": { + "A": { + "*": [ + "evm.deployedBytecode.immutableReferences", + "evm.bytecode", + "evm.deployedBytecode" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_yul_immutable_references/output.json b/test/cmdlineTests/standard_yul_immutable_references/output.json new file mode 100644 index 0000000000..42361097de --- /dev/null +++ b/test/cmdlineTests/standard_yul_immutable_references/output.json @@ -0,0 +1,52 @@ +{ + "contracts": + { + "A": + { + "YulTest": + { + "evm": + { + "bytecode": + { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "60298060156000396001600060010152806000f3fe7f000000000000000000000000000000000000000000000000000000000000000060005260206000f3", + "opcodes": "PUSH1 0x29 DUP1 PUSH1 0x15 PUSH1 0x0 CODECOPY PUSH1 0x1 PUSH1 0x0 PUSH1 0x1 ADD MSTORE DUP1 PUSH1 0x0 RETURN INVALID PUSH32 0x0 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 RETURN ", + "sourceMap": "42:19:0:-:0;100:4;77:21;74:1;65:40;133:1;122;109:26;;;149:4;146:1;139:15" + }, + "deployedBytecode": + { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": + { + "test": + [ + { + "length": 32, + "start": 1 + } + ] + }, + "linkReferences": {}, + "object": "7f000000000000000000000000000000000000000000000000000000000000000060005260206000f3", + "opcodes": "PUSH32 0x0 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 RETURN ", + "sourceMap": "203:21:0:-:0;200:1;193:32;241:4;238:1;231:15" + } + } + } + } + }, + "errors": + [ + { + "component": "general", + "formattedMessage": "Yul is still experimental. Please use the output with care.", + "message": "Yul is still experimental. Please use the output with care.", + "severity": "warning", + "type": "Warning" + } + ] +} diff --git a/test/cmdlineTests/standard_yul_object_name/output.json b/test/cmdlineTests/standard_yul_object_name/output.json index f2e85ed7cb..45280c8a1b 100644 --- a/test/cmdlineTests/standard_yul_object_name/output.json +++ b/test/cmdlineTests/standard_yul_object_name/output.json @@ -23,7 +23,7 @@ sub_0: assembly { /* \"A\":137:149 */ revert } -","bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""}},"ir":"object \"NamedObject\" { +","bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""}},"ir":"object \"NamedObject\" { code { let x := dataoffset(\"DataName\") sstore(add(x, 0), 0) From 2e2094ad820994161cf621c90a0e82f3d1c1d6f2 Mon Sep 17 00:00:00 2001 From: Naveen Sahu <42338831+theNvN@users.noreply.github.com> Date: Wed, 2 Feb 2022 02:02:31 +0530 Subject: [PATCH 0356/1748] plain `address` can be sent Ether too The docs state that a plain `address` cannot be sent Ether. But even though `send` and `transfer` members are not available for plain `address`, the `call` is. And `call` can be invoked upon a plain `address` type to send Ether to the address. For instance, the `someone` (`address` type) can be sent Ether by invoking `sendSomeone()` method in the following `Dummy` contract: ``` contract Dummy { address someone = 0xAb8...cb2; function balanceOf(address addr) public view returns (uint) { return addr.balance; } function sendToSomeone() public payable returns (bool) { (bool sent, ) = someone.call{value: msg.value}(""); return sent; } } ``` --- docs/types/value-types.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 30a8577963..0d6a30cd62 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -188,7 +188,8 @@ The address type comes in two flavours, which are largely identical: - ``address payable``: Same as ``address``, but with the additional members ``transfer`` and ``send``. The idea behind this distinction is that ``address payable`` is an address you can send Ether to, -while a plain ``address`` cannot be sent Ether. +while you are not supposed to send Ether to a plain ``address``, for example because it might be a smart contract +that was not built to accept Ether. Type conversions: From 6225dad3328ef1d8a440e2710545795f07bf9844 Mon Sep 17 00:00:00 2001 From: joshuatarkwski Date: Wed, 10 Nov 2021 15:16:11 +0100 Subject: [PATCH 0357/1748] Output searched locations on import failure. --- libsolidity/interface/FileReader.cpp | 23 ++++++++++++++----- .../output.json | 4 ++-- test/solc/CommandLineInterfaceAllowPaths.cpp | 6 ++--- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/libsolidity/interface/FileReader.cpp b/libsolidity/interface/FileReader.cpp index 47f4d2b5aa..8733e91a0d 100644 --- a/libsolidity/interface/FileReader.cpp +++ b/libsolidity/interface/FileReader.cpp @@ -116,7 +116,6 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so for (auto const& prefix: prefixes) { boost::filesystem::path canonicalPath = normalizeCLIPathForVFS(prefix / strippedSourceUnitName, SymlinkResolution::Enabled); - if (boost::filesystem::exists(canonicalPath)) candidates.push_back(std::move(canonicalPath)); } @@ -124,7 +123,12 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so auto pathToQuotedString = [](boost::filesystem::path const& _path){ return "\"" + _path.string() + "\""; }; if (candidates.empty()) - return ReadCallback::Result{false, "File not found."}; + return ReadCallback::Result{ + false, + "File not found. Searched the following locations: " + + joinHumanReadable(prefixes | ranges::views::transform(pathToQuotedString), ", ") + + "." + }; if (candidates.size() >= 2) return ReadCallback::Result{ @@ -135,11 +139,13 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so "." }; - FileSystemPathSet extraAllowedPaths = {m_basePath.empty() ? "." : m_basePath}; - extraAllowedPaths += m_includePaths; + FileSystemPathSet allowedPaths = + m_allowedDirectories + + decltype(allowedPaths){m_basePath.empty() ? "." : m_basePath} + + m_includePaths; bool isAllowed = false; - for (boost::filesystem::path const& allowedDir: m_allowedDirectories + extraAllowedPaths) + for (boost::filesystem::path const& allowedDir: allowedPaths) if (isPathPrefix(normalizeCLIPathForVFS(allowedDir, SymlinkResolution::Enabled), candidates[0])) { isAllowed = true; @@ -147,7 +153,12 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so } if (!isAllowed) - return ReadCallback::Result{false, "File outside of allowed directories."}; + return ReadCallback::Result{ + false, + "File outside of allowed directories. The following are allowed: " + + joinHumanReadable(allowedPaths | ranges::views::transform(pathToQuotedString), ", ") + + "." + }; if (!boost::filesystem::is_regular_file(candidates[0])) return ReadCallback::Result{false, "Not a valid file."}; 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 3f62fa0fe4..a97057c889 100644 --- a/test/cmdlineTests/standard_yul_single_file_via_urls/output.json +++ b/test/cmdlineTests/standard_yul_single_file_via_urls/output.json @@ -3,8 +3,8 @@ [ { "component": "general", - "formattedMessage": "Cannot import url (\"in.yul\"): File not found.", - "message": "Cannot import url (\"in.yul\"): File not found.", + "formattedMessage": "Cannot import url (\"in.yul\"): File not found. Searched the following locations: \"\".", + "message": "Cannot import url (\"in.yul\"): File not found. Searched the following locations: \"\".", "severity": "error", "type": "IOError" }, diff --git a/test/solc/CommandLineInterfaceAllowPaths.cpp b/test/solc/CommandLineInterfaceAllowPaths.cpp index 77f727014f..472f2184b4 100644 --- a/test/solc/CommandLineInterfaceAllowPaths.cpp +++ b/test/solc/CommandLineInterfaceAllowPaths.cpp @@ -100,7 +100,7 @@ ImportCheck checkImport( return ImportCheck::OK(); static regex const sourceNotFoundErrorRegex{ - R"(^Error \(6275\): Source ".+" not found: (.*)\.\n)" + R"(^Error \(6275\): Source "[^"]+" not found: (.*)\.\n)" R"(\s*--> .*:\d+:\d+:\n)" R"(\s*\|\n)" R"(\d+\s*\| import '.+';\n)" @@ -110,12 +110,12 @@ ImportCheck checkImport( smatch submatches; if (!regex_match(cliResult.stderrContent, submatches, sourceNotFoundErrorRegex)) return ImportCheck::Unknown("Unexpected stderr content: '" + cliResult.stderrContent + "'"); - if (submatches[1] != "File not found" && submatches[1] != "File outside of allowed directories") + if (submatches[1] != "File not found" && !boost::starts_with(string(submatches[1]), "File outside of allowed directories")) return ImportCheck::Unknown("Unexpected error message: '" + cliResult.stderrContent + "'"); if (submatches[1] == "File not found") return ImportCheck::FileNotFound(); - else if (submatches[1] == "File outside of allowed directories") + else if (boost::starts_with(string(submatches[1]), "File outside of allowed directories")) return ImportCheck::PathDisallowed(); else return ImportCheck::Unknown("Unexpected error message '" + submatches[1].str() + "'"); From 9e62f21b2586afb6544f6a03d9c4c2f088dd94f7 Mon Sep 17 00:00:00 2001 From: joshieDo Date: Mon, 17 Jan 2022 21:28:58 +0000 Subject: [PATCH 0358/1748] Add event and error identifiers to cli hashes cmd --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 32 +++++++++++++++++++++++++ libsolidity/interface/CompilerStack.h | 6 +++++ solc/CommandLineInterface.cpp | 20 ++++++++++++++-- test/cmdlineTests/hashes/args | 1 + test/cmdlineTests/hashes/input.sol | 28 ++++++++++++++++++++++ test/cmdlineTests/hashes/output | 23 ++++++++++++++++++ 7 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 test/cmdlineTests/hashes/args create mode 100644 test/cmdlineTests/hashes/input.sol create mode 100644 test/cmdlineTests/hashes/output diff --git a/Changelog.md b/Changelog.md index c938c44b0f..98515970f0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Language Features: Compiler Features: + * Commandline Interface: Event and error signatures are also returned when using ``--hashes``. * Yul Optimizer: Remove ``mstore`` and ``sstore`` operations if the slot already contains the same value. * Yul: Emit immutable references for pure yul code when requested. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 5292d5329f..a1c26ab374 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -75,6 +75,7 @@ #include #include #include +#include #include @@ -1024,6 +1025,37 @@ Json::Value CompilerStack::methodIdentifiers(string const& _contractName) const return methodIdentifiers; } +Json::Value CompilerStack::errorIdentifiers(string const& _contractName) const +{ + if (m_stackState < AnalysisPerformed) + solThrow(CompilerError, "Analysis was not successful."); + + Json::Value errorIdentifiers(Json::objectValue); + for (ErrorDefinition const* error: contractDefinition(_contractName).interfaceErrors()) + { + string signature = error->functionType(true)->externalSignature(); + errorIdentifiers[signature] = toHex(toCompactBigEndian(selectorFromSignature32(signature), 4)); + } + + return errorIdentifiers; +} + +Json::Value CompilerStack::eventIdentifiers(string const& _contractName) const +{ + if (m_stackState < AnalysisPerformed) + solThrow(CompilerError, "Analysis was not successful."); + + Json::Value eventIdentifiers(Json::objectValue); + for (EventDefinition const* event: contractDefinition(_contractName).interfaceEvents()) + if (!event->isAnonymous()) + { + string signature = event->functionType(true)->externalSignature(); + eventIdentifiers[signature] = toHex(u256(h256::Arith(keccak256(signature)))); + } + + return eventIdentifiers; +} + bytes CompilerStack::cborMetadata(string const& _contractName, bool _forIR) const { if (m_stackState < AnalysisPerformed) diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 3609662e02..2e1e687f71 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -330,6 +330,12 @@ class CompilerStack: public langutil::CharStreamProvider /// @returns a JSON representing a map of method identifiers (hashes) to function names. Json::Value methodIdentifiers(std::string const& _contractName) const; + /// @returns a JSON representing a map of error identifiers (hashes) to error names. + Json::Value errorIdentifiers(std::string const& _contractName) const; + + /// @returns a JSON representing a map of event identifiers (hashes) to event names. + Json::Value eventIdentifiers(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)); } diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 235059a02b..d96460fa1e 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -271,14 +271,30 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract) return; Json::Value methodIdentifiers = m_compiler->methodIdentifiers(_contract); - string out; + string out = "Function signatures:\n"; for (auto const& name: methodIdentifiers.getMemberNames()) out += methodIdentifiers[name].asString() + ": " + name + "\n"; + Json::Value errorIdentifiers = m_compiler->errorIdentifiers(_contract); + if (!errorIdentifiers.empty()) + { + out += "\nError signatures:\n"; + for (auto const& name: errorIdentifiers.getMemberNames()) + out += errorIdentifiers[name].asString() + ": " + name + "\n"; + } + + Json::Value eventIdentifiers = m_compiler->eventIdentifiers(_contract); + if (!eventIdentifiers.empty()) + { + out += "\nEvent signatures:\n"; + for (auto const& name: eventIdentifiers.getMemberNames()) + out += eventIdentifiers[name].asString() + ": " + name + "\n"; + } + if (!m_options.output.dir.empty()) createFile(m_compiler->filesystemFriendlyName(_contract) + ".signatures", out); else - sout() << "Function signatures:" << endl << out; + sout() << out; } void CommandLineInterface::handleMetadata(string const& _contract) diff --git a/test/cmdlineTests/hashes/args b/test/cmdlineTests/hashes/args new file mode 100644 index 0000000000..40469d358c --- /dev/null +++ b/test/cmdlineTests/hashes/args @@ -0,0 +1 @@ +--hashes \ No newline at end of file diff --git a/test/cmdlineTests/hashes/input.sol b/test/cmdlineTests/hashes/input.sol new file mode 100644 index 0000000000..1f5c758f71 --- /dev/null +++ b/test/cmdlineTests/hashes/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/hashes/output b/test/cmdlineTests/hashes/output new file mode 100644 index 0000000000..5223d732a3 --- /dev/null +++ b/test/cmdlineTests/hashes/output @@ -0,0 +1,23 @@ + +======= hashes/input.sol:C ======= +Function signatures: +3fc03eeb: f((uint256)) + +Error signatures: +619a0bb7: err(uint256,uint256) +82b5f64f: fileLevelError(uint256) +8c41f45c: libraryError(uint256) + +Event signatures: +2d4dd5fe18ada5a020a9f5591539a8dc3010a5c074ba6a70e1c956659f02786a: ev(uint256) + +======= hashes/input.sol:L ======= +Function signatures: + +Error signatures: +8c41f45c: libraryError(uint256) +c61c03f5: libraryErrorUnused(uint256) + +Event signatures: +81f3fb02f88d32d3bb08c80c9a622ca3b3223292f131c6ad049811f9a8a606dc: libraryEvent(uint256) +0a994ad3600197f16ffe1ea1101caea3174efe5ebd9ba9a75d6d5524c5de28cd: libraryEventUnused(uint256) From 3e7c68d9b09b59a959f32975f21ba3ec19152afa Mon Sep 17 00:00:00 2001 From: Marenz Date: Mon, 31 Jan 2022 17:52:08 +0100 Subject: [PATCH 0359/1748] Merge identifier query methods into one --- libsolidity/interface/CompilerStack.cpp | 33 +++++-------------- libsolidity/interface/CompilerStack.h | 10 ++---- libsolidity/interface/StandardCompiler.cpp | 2 +- solc/CommandLineInterface.cpp | 22 ++++++------- .../input.json | 17 ++++++++++ .../output.json | 1 + test/libsolidity/SemanticTest.cpp | 2 +- .../tools/ossfuzz/SolidityEvmoneInterface.cpp | 2 +- test/tools/ossfuzz/SolidityEvmoneInterface.h | 2 +- 9 files changed, 43 insertions(+), 48 deletions(-) create mode 100644 test/cmdlineTests/standard_method_identifiers_requested_empty/input.json create mode 100644 test/cmdlineTests/standard_method_identifiers_requested_empty/output.json diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index a1c26ab374..acf1932956 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1014,46 +1014,31 @@ Json::Value const& CompilerStack::natspecDev(Contract const& _contract) const return _contract.devDocumentation.init([&]{ return Natspec::devDocumentation(*_contract.contract); }); } -Json::Value CompilerStack::methodIdentifiers(string const& _contractName) const +Json::Value CompilerStack::contractIdentifiers(string const& _contractName) const { if (m_stackState < AnalysisPerformed) solThrow(CompilerError, "Analysis was not successful."); - Json::Value methodIdentifiers(Json::objectValue); - for (auto const& it: contractDefinition(_contractName).interfaceFunctions()) - methodIdentifiers[it.second->externalSignature()] = it.first.hex(); - return methodIdentifiers; -} + Json::Value contractIdentifiers(Json::objectValue); + // Always have a methods object + contractIdentifiers["methods"] = Json::objectValue; -Json::Value CompilerStack::errorIdentifiers(string const& _contractName) const -{ - if (m_stackState < AnalysisPerformed) - solThrow(CompilerError, "Analysis was not successful."); - - Json::Value errorIdentifiers(Json::objectValue); + for (auto const& it: contractDefinition(_contractName).interfaceFunctions()) + contractIdentifiers["methods"][it.second->externalSignature()] = it.first.hex(); for (ErrorDefinition const* error: contractDefinition(_contractName).interfaceErrors()) { string signature = error->functionType(true)->externalSignature(); - errorIdentifiers[signature] = toHex(toCompactBigEndian(selectorFromSignature32(signature), 4)); + contractIdentifiers["errors"][signature] = toHex(toCompactBigEndian(selectorFromSignature32(signature), 4)); } - return errorIdentifiers; -} - -Json::Value CompilerStack::eventIdentifiers(string const& _contractName) const -{ - if (m_stackState < AnalysisPerformed) - solThrow(CompilerError, "Analysis was not successful."); - - Json::Value eventIdentifiers(Json::objectValue); for (EventDefinition const* event: contractDefinition(_contractName).interfaceEvents()) if (!event->isAnonymous()) { string signature = event->functionType(true)->externalSignature(); - eventIdentifiers[signature] = toHex(u256(h256::Arith(keccak256(signature)))); + contractIdentifiers["events"][signature] = toHex(u256(h256::Arith(keccak256(signature)))); } - return eventIdentifiers; + return contractIdentifiers; } bytes CompilerStack::cborMetadata(string const& _contractName, bool _forIR) const diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 2e1e687f71..b1f85dd4df 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -327,14 +327,8 @@ class CompilerStack: public langutil::CharStreamProvider /// Prerequisite: Successful call to parse or compile. Json::Value const& natspecDev(std::string const& _contractName) const; - /// @returns a JSON representing a map of method identifiers (hashes) to function names. - Json::Value methodIdentifiers(std::string const& _contractName) const; - - /// @returns a JSON representing a map of error identifiers (hashes) to error names. - Json::Value errorIdentifiers(std::string const& _contractName) const; - - /// @returns a JSON representing a map of event identifiers (hashes) to event names. - Json::Value eventIdentifiers(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 contractIdentifiers(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)); } diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 5ccf2d447b..0e5b8aba46 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1298,7 +1298,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.legacyAssembly", wildcardMatchesExperimental)) evmData["legacyAssembly"] = compilerStack.assemblyJSON(contractName); if (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.methodIdentifiers", wildcardMatchesExperimental)) - evmData["methodIdentifiers"] = compilerStack.methodIdentifiers(contractName); + evmData["methodIdentifiers"] = compilerStack.contractIdentifiers(contractName)["methods"]; if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.gasEstimates", wildcardMatchesExperimental)) evmData["gasEstimates"] = compilerStack.gasEstimates(contractName); diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index d96460fa1e..ba557918c1 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -270,25 +270,23 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract) if (!m_options.compiler.outputs.signatureHashes) return; - Json::Value methodIdentifiers = m_compiler->methodIdentifiers(_contract); + Json::Value contractIdentifiers = m_compiler->contractIdentifiers(_contract); string out = "Function signatures:\n"; - for (auto const& name: methodIdentifiers.getMemberNames()) - out += methodIdentifiers[name].asString() + ": " + name + "\n"; + for (auto const& name: contractIdentifiers["methods"].getMemberNames()) + out += contractIdentifiers["methods"][name].asString() + ": " + name + "\n"; - Json::Value errorIdentifiers = m_compiler->errorIdentifiers(_contract); - if (!errorIdentifiers.empty()) + if (contractIdentifiers.isMember("errors")) { out += "\nError signatures:\n"; - for (auto const& name: errorIdentifiers.getMemberNames()) - out += errorIdentifiers[name].asString() + ": " + name + "\n"; + for (auto const& name: contractIdentifiers["errors"].getMemberNames()) + out += contractIdentifiers["errors"][name].asString() + ": " + name + "\n"; } - Json::Value eventIdentifiers = m_compiler->eventIdentifiers(_contract); - if (!eventIdentifiers.empty()) + if (contractIdentifiers.isMember("events")) { out += "\nEvent signatures:\n"; - for (auto const& name: eventIdentifiers.getMemberNames()) - out += eventIdentifiers[name].asString() + ": " + name + "\n"; + for (auto const& name: contractIdentifiers["events"].getMemberNames()) + out += contractIdentifiers["events"][name].asString() + ": " + name + "\n"; } if (!m_options.output.dir.empty()) @@ -838,7 +836,7 @@ void CommandLineInterface::handleCombinedJSON() m_compiler->runtimeObject(contractName).functionDebugData ); if (m_options.compiler.combinedJsonRequests->signatureHashes) - contractData[g_strSignatureHashes] = m_compiler->methodIdentifiers(contractName); + contractData[g_strSignatureHashes] = m_compiler->contractIdentifiers(contractName)["methods"]; if (m_options.compiler.combinedJsonRequests->natspecDev) contractData[g_strNatspecDev] = m_compiler->natspecDev(contractName); if (m_options.compiler.combinedJsonRequests->natspecUser) diff --git a/test/cmdlineTests/standard_method_identifiers_requested_empty/input.json b/test/cmdlineTests/standard_method_identifiers_requested_empty/input.json new file mode 100644 index 0000000000..28b9699b51 --- /dev/null +++ b/test/cmdlineTests/standard_method_identifiers_requested_empty/input.json @@ -0,0 +1,17 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; contract C { }" + } + }, + "settings": + { + "outputSelection": + { + "*": { "*": ["evm.methodIdentifiers"] } + } + } +} diff --git a/test/cmdlineTests/standard_method_identifiers_requested_empty/output.json b/test/cmdlineTests/standard_method_identifiers_requested_empty/output.json new file mode 100644 index 0000000000..7953dc1572 --- /dev/null +++ b/test/cmdlineTests/standard_method_identifiers_requested_empty/output.json @@ -0,0 +1 @@ +{"contracts":{"A":{"C":{"evm":{"methodIdentifiers":{}}}}},"sources":{"A":{"id":0}}} diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 4fbb16614c..342cf24fc2 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -435,7 +435,7 @@ TestCase::TestResult SemanticTest::runTest( { soltestAssert( m_allowNonExistingFunctions || - m_compiler.methodIdentifiers(m_compiler.lastContractName(m_sources.mainSourceFile)).isMember(test.call().signature), + m_compiler.contractIdentifiers(m_compiler.lastContractName(m_sources.mainSourceFile))["methods"].isMember(test.call().signature), "The function " + test.call().signature + " is not known to the compiler" ); diff --git a/test/tools/ossfuzz/SolidityEvmoneInterface.cpp b/test/tools/ossfuzz/SolidityEvmoneInterface.cpp index 4d536183c3..49b17930a3 100644 --- a/test/tools/ossfuzz/SolidityEvmoneInterface.cpp +++ b/test/tools/ossfuzz/SolidityEvmoneInterface.cpp @@ -58,7 +58,7 @@ optional SolidityCompilationFramework::compileContract() else contractName = m_compilerInput.contractName; evmasm::LinkerObject obj = m_compiler.object(contractName); - Json::Value methodIdentifiers = m_compiler.methodIdentifiers(contractName); + Json::Value methodIdentifiers = m_compiler.contractIdentifiers(contractName)["methods"]; return CompilerOutput{obj.bytecode, methodIdentifiers}; } } diff --git a/test/tools/ossfuzz/SolidityEvmoneInterface.h b/test/tools/ossfuzz/SolidityEvmoneInterface.h index 980eb9a842..51f6d5bdcc 100644 --- a/test/tools/ossfuzz/SolidityEvmoneInterface.h +++ b/test/tools/ossfuzz/SolidityEvmoneInterface.h @@ -91,7 +91,7 @@ class SolidityCompilationFramework /// @returns method identifiers in contract called @param _contractName. Json::Value methodIdentifiers(std::string const& _contractName) { - return m_compiler.methodIdentifiers(_contractName); + return m_compiler.contractIdentifiers(_contractName)["methods"]; } /// @returns Compilation output comprising EVM bytecode and list of /// method identifiers in contract if compilation is successful, From 0f05b1485e0fa8f54119ba0f48c3e7b7bcac3044 Mon Sep 17 00:00:00 2001 From: yatharthagoenka Date: Sat, 4 Sep 2021 15:37:18 +0530 Subject: [PATCH 0360/1748] CI: shared build and dependency installation steps --- .circleci/config.yml | 62 +++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 35 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 58a4c27428..be4940c636 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -214,6 +214,14 @@ defaults: command: ./test/lsp.py ./build/solc/solc - gitter_notify_failure_unless_pr + - steps_build: &steps_build + steps: + - checkout + - run: *run_build + - store_artifacts: *artifacts_solc + - persist_to_workspace: *artifacts_executables + - gitter_notify_failure_unless_pr + - steps_soltest_all: &steps_soltest_all steps: - checkout @@ -234,6 +242,14 @@ defaults: - store_artifacts: *artifacts_test_results - gitter_notify_failure_unless_pr + - steps_install_dependencies_osx: &steps_install_dependencies_osx + steps: + - restore_cache: + keys: + - dependencies-osx-{{ arch }}-{{ checksum ".circleci/osx_install_dependencies.sh" }} + - attach_workspace: + at: . + # -------------------------------------------------------------------------- # Base Image Templates @@ -748,12 +764,7 @@ jobs: CMAKE_OPTIONS: -DSANITIZE=address MAKEFLAGS: -j 3 CMAKE_BUILD_TYPE: Release - steps: - - checkout - - run: *run_build - - store_artifacts: *artifacts_solc - - persist_to_workspace: *artifacts_executables - - gitter_notify_failure_unless_pr + <<: *steps_build b_ubu_clang: &b_ubu_clang <<: *base_ubuntu2004_clang_large @@ -762,12 +773,7 @@ jobs: CC: clang CXX: clang++ MAKEFLAGS: -j 10 - steps: - - checkout - - run: *run_build - - store_artifacts: *artifacts_solc - - persist_to_workspace: *artifacts_executables - - gitter_notify_failure_unless_pr + <<: *steps_build b_ubu_asan_clang: &b_ubu_asan_clang # This runs a bit faster on large and xlarge but on nightly efficiency matters more. @@ -777,12 +783,7 @@ jobs: CXX: clang++ CMAKE_OPTIONS: -DSANITIZE=address MAKEFLAGS: -j 3 - steps: - - checkout - - run: *run_build - - store_artifacts: *artifacts_solc - - persist_to_workspace: *artifacts_executables - - gitter_notify_failure_unless_pr + <<: *steps_build b_ubu_ubsan_clang: &b_ubu_ubsan_clang # This runs a bit faster on large and xlarge but on nightly efficiency matters more. @@ -792,12 +793,7 @@ jobs: CXX: clang++ CMAKE_OPTIONS: -DSANITIZE=undefined MAKEFLAGS: -j 3 - steps: - - checkout - - run: *run_build - - store_artifacts: *artifacts_solc - - persist_to_workspace: *artifacts_executables - - gitter_notify_failure_unless_pr + <<: *steps_build b_ubu_release: &b_ubu_release <<: *b_ubu @@ -949,7 +945,7 @@ jobs: - build/test/tools/solfuzzer - gitter_notify_failure_unless_pr - t_osx_soltest: + t_osx_soltest: &t_osx_soltest <<: *base_osx environment: EVM: << pipeline.parameters.evm-version >> @@ -957,11 +953,9 @@ jobs: TERM: xterm steps: - checkout - - restore_cache: - keys: - - dependencies-osx-{{ arch }}-{{ checksum ".circleci/osx_install_dependencies.sh" }} - - attach_workspace: - at: . + - when: + condition: true + <<: *steps_install_dependencies_osx - run: *run_soltest - store_test_results: *store_test_results - store_artifacts: *artifacts_test_results @@ -971,11 +965,9 @@ jobs: <<: *base_osx steps: - checkout - - restore_cache: - keys: - - dependencies-osx-{{ arch }}-{{ checksum ".circleci/osx_install_dependencies.sh" }} - - attach_workspace: - at: . + - when: + condition: true + <<: *steps_install_dependencies_osx - run: *run_cmdline_tests - store_artifacts: *artifacts_test_results - gitter_notify_failure_unless_pr From bce5f9e0da5d96b4f0ed715d3138775016e6337f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 8 Feb 2022 14:55:49 +0100 Subject: [PATCH 0361/1748] CI: Store all artifacts in steps_build so that we can use it for b_ubu --- .circleci/config.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index be4940c636..6069ba4fbb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -219,6 +219,8 @@ defaults: - checkout - run: *run_build - store_artifacts: *artifacts_solc + - store_artifacts: *artifact_solidity_upgrade + - store_artifacts: *artifact_yul_phaser - persist_to_workspace: *artifacts_executables - gitter_notify_failure_unless_pr @@ -747,14 +749,7 @@ jobs: # 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_ubuntu2004_xlarge - steps: - - checkout - - run: *run_build - - store_artifacts: *artifacts_solc - - store_artifacts: *artifact_solidity_upgrade - - store_artifacts: *artifact_yul_phaser - - persist_to_workspace: *artifacts_executables - - gitter_notify_failure_unless_pr + <<: *steps_build # x64 ASAN build, for testing for memory related bugs b_ubu_asan: &b_ubu_asan From bdf84c991fe6902cce3bac52a4a970ae5a1bca3f Mon Sep 17 00:00:00 2001 From: yatharthagoenka Date: Sat, 4 Sep 2021 15:37:18 +0530 Subject: [PATCH 0362/1748] Ci: parameterize the clang sanitizer jobs --- .circleci/config.yml | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6069ba4fbb..39c219bcec 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -604,6 +604,15 @@ defaults: nodejs_version: '14' resource_class: medium + - job_b_ubu_asan_clang: &job_b_ubu_asan_clang + <<: *workflow_trigger_on_tags + name: b_ubu_asan_clang + cmake_options: -DSANITIZE=address + - job_b_ubu_ubsan_clang: &job_b_ubu_ubsan_clang + <<: *workflow_trigger_on_tags + name: b_ubu_ubsan_clang + cmake_options: -DSANITIZE=address + # ----------------------------------------------------------------------------------------------- jobs: @@ -770,24 +779,18 @@ jobs: MAKEFLAGS: -j 10 <<: *steps_build - b_ubu_asan_clang: &b_ubu_asan_clang - # This runs a bit faster on large and xlarge but on nightly efficiency matters more. - <<: *base_ubuntu2004_clang - environment: - CC: clang - CXX: clang++ - CMAKE_OPTIONS: -DSANITIZE=address - MAKEFLAGS: -j 3 - <<: *steps_build - - b_ubu_ubsan_clang: &b_ubu_ubsan_clang + b_ubu_san_clang: # This runs a bit faster on large and xlarge but on nightly efficiency matters more. + parameters: + cmake_options: + type: string <<: *base_ubuntu2004_clang environment: + TERM: xterm CC: clang CXX: clang++ - CMAKE_OPTIONS: -DSANITIZE=undefined MAKEFLAGS: -j 3 + CMAKE_OPTIONS: << parameters.cmake_options >> <<: *steps_build b_ubu_release: &b_ubu_release @@ -1506,13 +1509,13 @@ workflows: # ASan build and tests - b_ubu_asan: *workflow_trigger_on_tags - - b_ubu_asan_clang: *workflow_trigger_on_tags + - b_ubu_san_clang: *job_b_ubu_asan_clang - t_ubu_asan_soltest: *workflow_ubuntu2004_asan - t_ubu_asan_clang_soltest: *workflow_ubuntu2004_asan_clang - t_ubu_asan_cli: *workflow_ubuntu2004_asan # UBSan build and tests - - b_ubu_ubsan_clang: *workflow_trigger_on_tags + - b_ubu_san_clang: *job_b_ubu_ubsan_clang - t_ubu_ubsan_clang_soltest: *workflow_ubuntu2004_ubsan_clang - t_ubu_ubsan_clang_cli: *workflow_ubuntu2004_ubsan_clang From 46075d04d953981119f6376851051334076cf946 Mon Sep 17 00:00:00 2001 From: Marenz Date: Tue, 1 Feb 2022 15:42:08 +0100 Subject: [PATCH 0363/1748] Include used events in ``--hashes`` output --- libsolidity/ast/AST.cpp | 20 ++++++++++++------ libsolidity/ast/AST.h | 3 ++- libsolidity/interface/ABI.cpp | 2 +- libsolidity/interface/CompilerStack.cpp | 21 ++++++++++++------- libsolidity/interface/CompilerStack.h | 2 +- libsolidity/interface/Natspec.cpp | 2 +- libsolidity/interface/StandardCompiler.cpp | 2 +- solc/CommandLineInterface.cpp | 20 +++++++++--------- test/cmdlineTests/hashes/output | 1 + test/libsolidity/SemanticTest.cpp | 2 +- .../tools/ossfuzz/SolidityEvmoneInterface.cpp | 2 +- test/tools/ossfuzz/SolidityEvmoneInterface.h | 2 +- 12 files changed, 47 insertions(+), 32 deletions(-) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index f2b7369b71..2a7609de85 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -192,7 +192,7 @@ FunctionDefinition const* ContractDefinition::receiveFunction() const return nullptr; } -vector const& ContractDefinition::interfaceEvents() const +vector const& ContractDefinition::definedInterfaceEvents() const { return m_interfaceEvents.init([&]{ set eventsSeen; @@ -213,11 +213,20 @@ vector const& ContractDefinition::interfaceEvents() cons interfaceEvents.push_back(e); } } - return interfaceEvents; }); } +vector const ContractDefinition::usedInterfaceEvents() const +{ + solAssert(annotation().creationCallGraph.set(), ""); + + return convertContainer>( + (*annotation().creationCallGraph)->emittedEvents + + (*annotation().deployedCallGraph)->emittedEvents + ); +} + vector ContractDefinition::interfaceErrors(bool _requireCallGraph) const { set result; @@ -227,10 +236,9 @@ vector ContractDefinition::interfaceErrors(bool _require if (_requireCallGraph) solAssert(annotation().creationCallGraph.set(), ""); if (annotation().creationCallGraph.set()) - { - result += (*annotation().creationCallGraph)->usedErrors; - result += (*annotation().deployedCallGraph)->usedErrors; - } + result += + (*annotation().creationCallGraph)->usedErrors + + (*annotation().deployedCallGraph)->usedErrors; return convertContainer>(move(result)); } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index b7d5db8058..c35c69c9d2 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -519,7 +519,8 @@ class ContractDefinition: public Declaration, public StructurallyDocumented, pub return ranges::subrange(b, e) | ranges::views::values; } std::vector events() const { return filteredNodes(m_subNodes); } - std::vector const& interfaceEvents() const; + std::vector const& definedInterfaceEvents() const; + std::vector const usedInterfaceEvents() const; /// @returns all errors defined in this contract or any base contract /// and all errors referenced during execution. /// @param _requireCallGraph if false, do not fail if the call graph has not been computed yet. diff --git a/libsolidity/interface/ABI.cpp b/libsolidity/interface/ABI.cpp index 9c7a645b6f..eab1801c6a 100644 --- a/libsolidity/interface/ABI.cpp +++ b/libsolidity/interface/ABI.cpp @@ -101,7 +101,7 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability()); abi.emplace(std::move(method)); } - for (auto const& it: _contractDef.interfaceEvents()) + for (auto const& it: _contractDef.definedInterfaceEvents()) { Json::Value event{Json::objectValue}; event["type"] = "event"; diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index acf1932956..7a8bc4ddbf 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -81,6 +81,8 @@ #include +#include + #include #include #include @@ -1014,31 +1016,34 @@ Json::Value const& CompilerStack::natspecDev(Contract const& _contract) const return _contract.devDocumentation.init([&]{ return Natspec::devDocumentation(*_contract.contract); }); } -Json::Value CompilerStack::contractIdentifiers(string const& _contractName) const +Json::Value CompilerStack::interfaceSymbols(string const& _contractName) const { if (m_stackState < AnalysisPerformed) solThrow(CompilerError, "Analysis was not successful."); - Json::Value contractIdentifiers(Json::objectValue); + Json::Value interfaceSymbols(Json::objectValue); // Always have a methods object - contractIdentifiers["methods"] = Json::objectValue; + interfaceSymbols["methods"] = Json::objectValue; for (auto const& it: contractDefinition(_contractName).interfaceFunctions()) - contractIdentifiers["methods"][it.second->externalSignature()] = it.first.hex(); + interfaceSymbols["methods"][it.second->externalSignature()] = it.first.hex(); for (ErrorDefinition const* error: contractDefinition(_contractName).interfaceErrors()) { string signature = error->functionType(true)->externalSignature(); - contractIdentifiers["errors"][signature] = toHex(toCompactBigEndian(selectorFromSignature32(signature), 4)); + interfaceSymbols["errors"][signature] = toHex(toCompactBigEndian(selectorFromSignature32(signature), 4)); } - for (EventDefinition const* event: contractDefinition(_contractName).interfaceEvents()) + for (EventDefinition const* event: ranges::concat_view( + contractDefinition(_contractName).definedInterfaceEvents(), + contractDefinition(_contractName).usedInterfaceEvents() + )) if (!event->isAnonymous()) { string signature = event->functionType(true)->externalSignature(); - contractIdentifiers["events"][signature] = toHex(u256(h256::Arith(keccak256(signature)))); + interfaceSymbols["events"][signature] = toHex(u256(h256::Arith(keccak256(signature)))); } - return contractIdentifiers; + return interfaceSymbols; } bytes CompilerStack::cborMetadata(string const& _contractName, bool _forIR) const diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index b1f85dd4df..c1f15a4804 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -328,7 +328,7 @@ class CompilerStack: public langutil::CharStreamProvider Json::Value 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 contractIdentifiers(std::string const& _contractName) const; + Json::Value 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)); } diff --git a/libsolidity/interface/Natspec.cpp b/libsolidity/interface/Natspec.cpp index 533cbaa3dd..4496904937 100644 --- a/libsolidity/interface/Natspec.cpp +++ b/libsolidity/interface/Natspec.cpp @@ -78,7 +78,7 @@ Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef) doc["methods"][it.second->externalSignature()]["notice"] = value; } - for (auto const& event: _contractDef.interfaceEvents()) + for (auto const& event: _contractDef.definedInterfaceEvents()) { string value = extractDoc(event->annotation().docTags, "notice"); if (!value.empty()) diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 0e5b8aba46..75876d9353 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1298,7 +1298,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.legacyAssembly", wildcardMatchesExperimental)) evmData["legacyAssembly"] = compilerStack.assemblyJSON(contractName); if (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.methodIdentifiers", wildcardMatchesExperimental)) - evmData["methodIdentifiers"] = compilerStack.contractIdentifiers(contractName)["methods"]; + evmData["methodIdentifiers"] = compilerStack.interfaceSymbols(contractName)["methods"]; if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.gasEstimates", wildcardMatchesExperimental)) evmData["gasEstimates"] = compilerStack.gasEstimates(contractName); diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index ba557918c1..bafd3a7356 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -270,23 +270,23 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract) if (!m_options.compiler.outputs.signatureHashes) return; - Json::Value contractIdentifiers = m_compiler->contractIdentifiers(_contract); + Json::Value interfaceSymbols = m_compiler->interfaceSymbols(_contract); string out = "Function signatures:\n"; - for (auto const& name: contractIdentifiers["methods"].getMemberNames()) - out += contractIdentifiers["methods"][name].asString() + ": " + name + "\n"; + for (auto const& name: interfaceSymbols["methods"].getMemberNames()) + out += interfaceSymbols["methods"][name].asString() + ": " + name + "\n"; - if (contractIdentifiers.isMember("errors")) + if (interfaceSymbols.isMember("errors")) { out += "\nError signatures:\n"; - for (auto const& name: contractIdentifiers["errors"].getMemberNames()) - out += contractIdentifiers["errors"][name].asString() + ": " + name + "\n"; + for (auto const& name: interfaceSymbols["errors"].getMemberNames()) + out += interfaceSymbols["errors"][name].asString() + ": " + name + "\n"; } - if (contractIdentifiers.isMember("events")) + if (interfaceSymbols.isMember("events")) { out += "\nEvent signatures:\n"; - for (auto const& name: contractIdentifiers["events"].getMemberNames()) - out += contractIdentifiers["events"][name].asString() + ": " + name + "\n"; + for (auto const& name: interfaceSymbols["events"].getMemberNames()) + out += interfaceSymbols["events"][name].asString() + ": " + name + "\n"; } if (!m_options.output.dir.empty()) @@ -836,7 +836,7 @@ void CommandLineInterface::handleCombinedJSON() m_compiler->runtimeObject(contractName).functionDebugData ); if (m_options.compiler.combinedJsonRequests->signatureHashes) - contractData[g_strSignatureHashes] = m_compiler->contractIdentifiers(contractName)["methods"]; + contractData[g_strSignatureHashes] = m_compiler->interfaceSymbols(contractName)["methods"]; if (m_options.compiler.combinedJsonRequests->natspecDev) contractData[g_strNatspecDev] = m_compiler->natspecDev(contractName); if (m_options.compiler.combinedJsonRequests->natspecUser) diff --git a/test/cmdlineTests/hashes/output b/test/cmdlineTests/hashes/output index 5223d732a3..b010456d39 100644 --- a/test/cmdlineTests/hashes/output +++ b/test/cmdlineTests/hashes/output @@ -10,6 +10,7 @@ Error signatures: Event signatures: 2d4dd5fe18ada5a020a9f5591539a8dc3010a5c074ba6a70e1c956659f02786a: ev(uint256) +81f3fb02f88d32d3bb08c80c9a622ca3b3223292f131c6ad049811f9a8a606dc: libraryEvent(uint256) ======= hashes/input.sol:L ======= Function signatures: diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 342cf24fc2..1f07f177d4 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -435,7 +435,7 @@ TestCase::TestResult SemanticTest::runTest( { soltestAssert( m_allowNonExistingFunctions || - m_compiler.contractIdentifiers(m_compiler.lastContractName(m_sources.mainSourceFile))["methods"].isMember(test.call().signature), + m_compiler.interfaceSymbols(m_compiler.lastContractName(m_sources.mainSourceFile))["methods"].isMember(test.call().signature), "The function " + test.call().signature + " is not known to the compiler" ); diff --git a/test/tools/ossfuzz/SolidityEvmoneInterface.cpp b/test/tools/ossfuzz/SolidityEvmoneInterface.cpp index 49b17930a3..ff9fcf2d8d 100644 --- a/test/tools/ossfuzz/SolidityEvmoneInterface.cpp +++ b/test/tools/ossfuzz/SolidityEvmoneInterface.cpp @@ -58,7 +58,7 @@ optional SolidityCompilationFramework::compileContract() else contractName = m_compilerInput.contractName; evmasm::LinkerObject obj = m_compiler.object(contractName); - Json::Value methodIdentifiers = m_compiler.contractIdentifiers(contractName)["methods"]; + Json::Value methodIdentifiers = m_compiler.interfaceSymbols(contractName)["methods"]; return CompilerOutput{obj.bytecode, methodIdentifiers}; } } diff --git a/test/tools/ossfuzz/SolidityEvmoneInterface.h b/test/tools/ossfuzz/SolidityEvmoneInterface.h index 51f6d5bdcc..da0fed58f2 100644 --- a/test/tools/ossfuzz/SolidityEvmoneInterface.h +++ b/test/tools/ossfuzz/SolidityEvmoneInterface.h @@ -91,7 +91,7 @@ class SolidityCompilationFramework /// @returns method identifiers in contract called @param _contractName. Json::Value methodIdentifiers(std::string const& _contractName) { - return m_compiler.contractIdentifiers(_contractName)["methods"]; + return m_compiler.interfaceSymbols(_contractName)["methods"]; } /// @returns Compilation output comprising EVM bytecode and list of /// method identifiers in contract if compilation is successful, From d511fe93ab480f22a55e8cb6329abb20ad5c8712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Mon, 24 Jan 2022 14:01:58 +0100 Subject: [PATCH 0364/1748] CI: Fix job name for PRBMath external test --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 39c219bcec..af58d830f1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -583,7 +583,7 @@ defaults: project: uniswap binary_type: native nodejs_version: '16' - - job_native_test_prb_math: &job_native_test_prb_math + - job_native_test_ext_prb_math: &job_native_test_ext_prb_math <<: *workflow_ubuntu2004_static name: t_native_test_ext_prb_math project: prb-math @@ -1454,7 +1454,7 @@ workflows: - t_ems_ext: *job_native_test_ext_pool_together - t_ems_ext: *job_native_test_ext_perpetual_pools - t_ems_ext: *job_native_test_ext_uniswap - - t_ems_ext: *job_native_test_prb_math + - t_ems_ext: *job_native_test_ext_prb_math - t_ems_ext: *job_native_test_ext_elementfi # Windows build and tests From 3e1aee17455b1d58fa485587df52db4ee7a2fc8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 18 Dec 2021 00:08:59 +0100 Subject: [PATCH 0365/1748] externalTests: Clean the build/ dir for Hardhat too --- test/externalTests/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index 10df975256..cd0afb8a49 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -320,7 +320,7 @@ function truffle_clean function hardhat_clean { - rm -rf artifacts/ cache/ + rm -rf build/ artifacts/ cache/ } function run_test From 7fc225384132fff74cda971eaf7927fb07c921b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 22 Dec 2021 17:06:52 +0100 Subject: [PATCH 0366/1748] externalTests: Make comments about failing presets less terse --- test/externalTests/gnosis-v2.sh | 6 +++--- test/externalTests/gnosis.sh | 8 ++++---- test/externalTests/zeppelin.sh | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index 8ad070d113..a48dddf9c1 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -40,12 +40,12 @@ function gnosis_safe_test local config_file="truffle-config.js" local compile_only_presets=( - legacy-no-optimize # "Error: while migrating GnosisSafe: Returned error: base fee exceeds gas limit" + legacy-no-optimize # Compiles but migrations run out of gas: "Error: while migrating GnosisSafe: Returned error: base fee exceeds gas limit" ) local settings_presets=( "${compile_only_presets[@]}" - #ir-no-optimize # "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." - #ir-optimize-evm-only # "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." + #ir-no-optimize # Compilation fails with "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." + #ir-optimize-evm-only # Compilation fails with "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." ir-optimize-evm+yul legacy-optimize-evm-only legacy-optimize-evm+yul diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index edada2fef3..1b430a9ae5 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -42,11 +42,11 @@ function gnosis_safe_test local compile_only_presets=() local settings_presets=( "${compile_only_presets[@]}" - #ir-no-optimize # "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." - #ir-optimize-evm-only # "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." + #ir-no-optimize # Compilation fails with "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." + #ir-optimize-evm-only # Compilation fails with "YulException: Variable var_call_430_mpos is 1 slot(s) too deep inside the stack." ir-optimize-evm+yul - #legacy-no-optimize # "Stack too deep" error - #legacy-optimize-evm-only # "Stack too deep" error + #legacy-no-optimize # Compilation fails with "Stack too deep" error + #legacy-optimize-evm-only # Compilation fails with "Stack too deep" error legacy-optimize-evm+yul ) diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index 5c54ceb8b2..d365dfe2a8 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -44,8 +44,8 @@ function zeppelin_test ) local settings_presets=( "${compile_only_presets[@]}" - #ir-no-optimize # "YulException: Variable var_account_852 is 4 slot(s) too deep inside the stack." - #ir-optimize-evm-only # "YulException: Variable var_account_852 is 4 slot(s) too deep inside the stack." + #ir-no-optimize # Compilation fails with "YulException: Variable var_account_852 is 4 slot(s) too deep inside the stack." + #ir-optimize-evm-only # Compilation fails with "YulException: Variable var_account_852 is 4 slot(s) too deep inside the stack." legacy-no-optimize legacy-optimize-evm-only legacy-optimize-evm+yul From a7852cba75e58b86955a0b8a5015b8282ca406b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 17 Dec 2021 22:42:45 +0100 Subject: [PATCH 0367/1748] Python script for parsing eth-gas-reporter output --- scripts/externalTests/parse_eth_gas_report.py | 269 +++++++++++++ .../fixtures/eth_gas_report_gnosis.rst | 381 ++++++++++++++++++ ...test_externalTests_parse_eth_gas_report.py | 219 ++++++++++ 3 files changed, 869 insertions(+) create mode 100755 scripts/externalTests/parse_eth_gas_report.py create mode 100644 test/scripts/fixtures/eth_gas_report_gnosis.rst create mode 100644 test/scripts/test_externalTests_parse_eth_gas_report.py diff --git a/scripts/externalTests/parse_eth_gas_report.py b/scripts/externalTests/parse_eth_gas_report.py new file mode 100755 index 0000000000..c5cc58e587 --- /dev/null +++ b/scripts/externalTests/parse_eth_gas_report.py @@ -0,0 +1,269 @@ +#!/usr/bin/env python3 +# coding=utf-8 + +from dataclasses import asdict, dataclass, field +from typing import Dict, Optional, Tuple +import json +import re +import sys + +REPORT_HEADER_REGEX = re.compile(r''' + ^[|\s]+ Solc[ ]version:\s*(?P[\w\d.]+) + [|\s]+ Optimizer[ ]enabled:\s*(?P[\w]+) + [|\s]+ Runs:\s*(?P[\d]+) + [|\s]+ Block[ ]limit:\s*(?P[\d]+)\s*gas + [|\s]+$ +''', re.VERBOSE) +METHOD_HEADER_REGEX = re.compile(r'^[|\s]+Methods[|\s]+$') +METHOD_COLUMN_HEADERS_REGEX = re.compile(r''' + ^[|\s]+ Contract + [|\s]+ Method + [|\s]+ Min + [|\s]+ Max + [|\s]+ Avg + [|\s]+ \#[ ]calls + [|\s]+ \w+[ ]\(avg\) + [|\s]+$ +''', re.VERBOSE) +METHOD_ROW_REGEX = re.compile(r''' + ^[|\s]+ (?P[^|]+) + [|\s]+ (?P[^|]+) + [|\s]+ (?P[^|]+) + [|\s]+ (?P[^|]+) + [|\s]+ (?P[^|]+) + [|\s]+ (?P[^|]+) + [|\s]+ (?P[^|]+) + [|\s]+$ +''', re.VERBOSE) +FRAME_REGEX = re.compile(r'^[-|\s]+$') +DEPLOYMENT_HEADER_REGEX = re.compile(r'^[|\s]+Deployments[|\s]+% of limit[|\s]+$') +DEPLOYMENT_ROW_REGEX = re.compile(r''' + ^[|\s]+ (?P[^|]+) + [|\s]+ (?P[^|]+) + [|\s]+ (?P[^|]+) + [|\s]+ (?P[^|]+) + [|\s]+ (?P[^|]+)\s*% + [|\s]+ (?P[^|]+) + [|\s]+$ +''', re.VERBOSE) + + +class ReportError(Exception): + pass + +class ReportValidationError(ReportError): + pass + +class ReportParsingError(Exception): + def __init__(self, message: str, line: str, line_number: int): + # pylint: disable=useless-super-delegation # It's not useless, it adds type annotations. + super().__init__(message, line, line_number) + + def __str__(self): + return f"Parsing error on line {self.args[2] + 1}: {self.args[0]}\n{self.args[1]}" + + +@dataclass(frozen=True) +class MethodGasReport: + min_gas: int + max_gas: int + avg_gas: int + call_count: int + total_gas: int = field(init=False) + + def __post_init__(self): + object.__setattr__(self, 'total_gas', self.avg_gas * self.call_count) + + +@dataclass(frozen=True) +class ContractGasReport: + min_deployment_gas: Optional[int] + max_deployment_gas: Optional[int] + avg_deployment_gas: Optional[int] + methods: Optional[Dict[str, MethodGasReport]] + total_method_gas: int = field(init=False, default=0) + + def __post_init__(self): + if self.methods is not None: + object.__setattr__(self, 'total_method_gas', sum(method.total_gas for method in self.methods.values())) + + +@dataclass(frozen=True) +class GasReport: + solc_version: str + optimize: bool + runs: int + block_limit: int + contracts: Dict[str, ContractGasReport] + total_method_gas: int = field(init=False) + total_deployment_gas: int = field(init=False) + + def __post_init__(self): + object.__setattr__(self, 'total_method_gas', sum( + total_method_gas + for total_method_gas in (contract.total_method_gas for contract in self.contracts.values()) + if total_method_gas is not None + )) + object.__setattr__(self, 'total_deployment_gas', sum( + contract.avg_deployment_gas + for contract in self.contracts.values() + if contract.avg_deployment_gas is not None + )) + + def to_json(self): + return json.dumps(asdict(self), indent=4, sort_keys=True) + + +def parse_bool(input_string: str) -> bool: + if input_string == 'true': + return True + elif input_string == 'false': + return True + else: + raise ValueError(f"Invalid boolean value: '{input_string}'") + + +def parse_optional_int(input_string: str, default: Optional[int] = None) -> Optional[int]: + if input_string.strip() == '-': + return default + + return int(input_string) + + +def parse_report_header(line: str) -> Optional[dict]: + match = REPORT_HEADER_REGEX.match(line) + if match is None: + return None + + return { + 'solc_version': match.group('solc_version'), + 'optimize': parse_bool(match.group('optimize')), + 'runs': int(match.group('runs')), + 'block_limit': int(match.group('block_limit')), + } + + +def parse_method_row(line: str, line_number: int) -> Optional[Tuple[str, str, MethodGasReport]]: + match = METHOD_ROW_REGEX.match(line) + if match is None: + raise ReportParsingError("Expected a table row with method details.", line, line_number) + + avg_gas = parse_optional_int(match['avg']) + call_count = int(match['call_count']) + + if avg_gas is None and call_count == 0: + # No calls, no gas values. Uninteresting. Skip the row. + return None + + return ( + match['contract'].strip(), + match['method'].strip(), + MethodGasReport( + min_gas=parse_optional_int(match['min'], avg_gas), + max_gas=parse_optional_int(match['max'], avg_gas), + avg_gas=avg_gas, + call_count=call_count, + ) + ) + + +def parse_deployment_row(line: str, line_number: int) -> Tuple[str, int, int, int]: + match = DEPLOYMENT_ROW_REGEX.match(line) + if match is None: + raise ReportParsingError("Expected a table row with deployment details.", line, line_number) + + return ( + match['contract'].strip(), + parse_optional_int(match['min'].strip()), + parse_optional_int(match['max'].strip()), + int(match['avg'].strip()), + ) + + +def preprocess_unicode_frames(input_string: str) -> str: + # The report has a mix of normal pipe chars and its unicode variant. + # Let's just replace all frame chars with normal pipes for easier parsing. + return input_string.replace('\u2502', '|').replace('·', '|') + + +def parse_report(rst_report: str) -> GasReport: + report_params = None + methods_by_contract = {} + deployment_costs = {} + expected_row_type = None + + for line_number, line in enumerate(preprocess_unicode_frames(rst_report).splitlines()): + try: + if ( + line.strip() == "" or + FRAME_REGEX.match(line) is not None or + METHOD_COLUMN_HEADERS_REGEX.match(line) is not None + ): + continue + if METHOD_HEADER_REGEX.match(line) is not None: + expected_row_type = 'method' + continue + if DEPLOYMENT_HEADER_REGEX.match(line) is not None: + expected_row_type = 'deployment' + continue + + new_report_params = parse_report_header(line) + if new_report_params is not None: + if report_params is not None: + raise ReportParsingError("Duplicate report header.", line, line_number) + + report_params = new_report_params + continue + + if expected_row_type == 'method': + parsed_row = parse_method_row(line, line_number) + if parsed_row is None: + continue + + (contract, method, method_report) = parsed_row + + if contract not in methods_by_contract: + methods_by_contract[contract] = {} + + if method in methods_by_contract[contract]: + # Report must be generated with full signatures for method names to be unambiguous. + raise ReportParsingError(f"Duplicate method row for '{contract}.{method}'.", line, line_number) + + methods_by_contract[contract][method] = method_report + elif expected_row_type == 'deployment': + (contract, min_gas, max_gas, avg_gas) = parse_deployment_row(line, line_number) + + if contract in deployment_costs: + raise ReportParsingError(f"Duplicate contract deployment row for '{contract}'.", line, line_number) + + deployment_costs[contract] = (min_gas, max_gas, avg_gas) + else: + assert expected_row_type is None + raise ReportParsingError("Found data row without a section header.", line, line_number) + + except ValueError as error: + raise ReportParsingError(error.args[0], line, line_number) from error + + if report_params is None: + raise ReportValidationError("Report header not found.") + + report_params['contracts'] = { + contract: ContractGasReport( + min_deployment_gas=deployment_costs.get(contract, (None, None, None))[0], + max_deployment_gas=deployment_costs.get(contract, (None, None, None))[1], + avg_deployment_gas=deployment_costs.get(contract, (None, None, None))[2], + methods=methods_by_contract.get(contract), + ) + for contract in methods_by_contract.keys() | deployment_costs.keys() + } + + return GasReport(**report_params) + + +if __name__ == "__main__": + try: + report = parse_report(sys.stdin.read()) + print(report.to_json()) + except ReportError as exception: + print(f"{exception}", file=sys.stderr) + sys.exit(1) diff --git a/test/scripts/fixtures/eth_gas_report_gnosis.rst b/test/scripts/fixtures/eth_gas_report_gnosis.rst new file mode 100644 index 0000000000..c2e77f9bed --- /dev/null +++ b/test/scripts/fixtures/eth_gas_report_gnosis.rst @@ -0,0 +1,381 @@ +·----------------------------------------------------------------------------------------------------------------------------------------|---------------------------|-------------|------------------------------· +| Solc version: 0.8.10 · Optimizer enabled: true · Runs: 200 · Block limit: 100000000 gas │ +·········································································································································|···························|·············|······························· +| Methods │ +·································|·······································································································|·············|·············|·············|···············|··············· +| Contract · Method · Min · Max · Avg · # calls · eur (avg) │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · getMessageHash(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · getMessageHashForSafe(address,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · getModules() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · isValidSignature(bytes,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · isValidSignature(bytes32,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · NAME() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · onERC1155BatchReceived(address,address,uint256[],uint256[],bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · onERC1155Received(address,address,uint256,uint256,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · onERC721Received(address,address,uint256,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · simulate(address,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · supportsInterface(bytes4) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · tokensReceived(address,address,address,uint256,bytes,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CompatibilityFallbackHandler · VERSION() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CreateCall · performCreate(uint256,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| CreateCall · performCreate2(uint256,bytes,bytes32) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DebugTransactionGuard · checkAfterExecution(bytes32,bool) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DebugTransactionGuard · checkTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DebugTransactionGuard · supportsInterface(bytes4) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DebugTransactionGuard · txNonces(bytes32) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DefaultCallbackHandler · NAME() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DefaultCallbackHandler · onERC1155BatchReceived(address,address,uint256[],uint256[],bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DefaultCallbackHandler · onERC1155Received(address,address,uint256,uint256,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DefaultCallbackHandler · onERC721Received(address,address,uint256,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DefaultCallbackHandler · supportsInterface(bytes4) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DefaultCallbackHandler · tokensReceived(address,address,address,uint256,bytes,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DefaultCallbackHandler · VERSION() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DelegateCallTransactionGuard · allowedTarget() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DelegateCallTransactionGuard · checkAfterExecution(bytes32,bool) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DelegateCallTransactionGuard · checkTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| DelegateCallTransactionGuard · supportsInterface(bytes4) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC1155Token · balanceOf(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC1155Token · mint(address,uint256,uint256,bytes) · 47934 · 59804 · 57826 · 6 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC1155Token · safeTransferFrom(address,address,uint256,uint256,bytes) · - · - · 53900 · 2 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · allowance(address,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · approve(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · balanceOf(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · decimals() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · decreaseAllowance(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · increaseAllowance(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · name() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · symbol() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · totalSupply() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · transfer(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20 · transferFrom(address,address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · allowance(address,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · approve(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · balanceOf(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · decimals() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · decreaseAllowance(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · increaseAllowance(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · name() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · symbol() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · totalSupply() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · transfer(address,uint256) · - · - · 51567 · 8 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ERC20Token · transferFrom(address,address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| FallbackManager · setFallbackHandler(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · addOwnerWithThreshold(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · approvedHashes(address,bytes32) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · approveHash(bytes32) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · changeThreshold(uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · checkNSignatures(bytes32,bytes,bytes,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · checkSignatures(bytes32,bytes,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · disableModule(address,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · domainSeparator() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · enableModule(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · encodeTransactionData(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes) · 59563 · 151736 · 94816 · 85 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · execTransactionFromModule(address,uint256,bytes,uint8) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · execTransactionFromModuleReturnData(address,uint256,bytes,uint8) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · getChainId() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · getModulesPaginated(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · getOwners() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · getStorageAt(uint256,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · getThreshold() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · getTransactionHash(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · isModuleEnabled(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · isOwner(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · nonce() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · removeOwner(address,address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · requiredTxGas(address,uint256,bytes,uint8) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · setFallbackHandler(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · setGuard(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · setup(address[],uint256,address,bytes,address,address,uint256,address) · 167642 · 263690 · 201944 · 49 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · signedMessages(bytes32) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · simulateAndRevert(address,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · swapOwner(address,address,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafe · VERSION() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · addOwnerWithThreshold(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · approvedHashes(address,bytes32) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · approveHash(bytes32) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · changeThreshold(uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · checkNSignatures(bytes32,bytes,bytes,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · checkSignatures(bytes32,bytes,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · disableModule(address,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · domainSeparator() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · enableModule(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · encodeTransactionData(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · execTransactionFromModule(address,uint256,bytes,uint8) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · execTransactionFromModuleReturnData(address,uint256,bytes,uint8) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · getChainId() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · getModulesPaginated(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · getOwners() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · getStorageAt(uint256,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · getThreshold() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · getTransactionHash(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · isModuleEnabled(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · isOwner(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · nonce() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · removeOwner(address,address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · requiredTxGas(address,uint256,bytes,uint8) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · setFallbackHandler(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · setGuard(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · setup(address[],uint256,address,bytes,address,address,uint256,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · signedMessages(bytes32) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · simulateAndRevert(address,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · swapOwner(address,address,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeL2 · VERSION() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeProxyFactory · calculateCreateProxyWithNonceAddress(address,bytes,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeProxyFactory · createProxy(address,bytes) · 105568 · 105580 · 105568 · 52 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeProxyFactory · createProxyWithCallback(address,bytes,uint256,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeProxyFactory · createProxyWithNonce(address,bytes,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeProxyFactory · proxyCreationCode() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GnosisSafeProxyFactory · proxyRuntimeCode() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| GuardManager · setGuard(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| Migration · migrate() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| Migration · migrationSingleton() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| Migration · safe120Singleton() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · DEFAULT_FALLBACK_VALUE() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenAnyReturn(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenAnyReturnAddress(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenAnyReturnBool(bool) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenAnyReturnUint(uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenAnyRevert() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenAnyRevertWithMessage(string) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenAnyRunOutOfGas() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenCalldataReturn(bytes,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenCalldataReturnAddress(bytes,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenCalldataReturnBool(bytes,bool) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenCalldataReturnUint(bytes,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenCalldataRevert(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenCalldataRevertWithMessage(bytes,string) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenCalldataRunOutOfGas(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenMethodReturn(bytes,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenMethodReturnAddress(bytes,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenMethodReturnBool(bytes,bool) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenMethodReturnUint(bytes,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenMethodRevert(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenMethodRevertWithMessage(bytes,string) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · givenMethodRunOutOfGas(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · invocationCount() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · invocationCountForCalldata(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · invocationCountForMethod(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · MOCKS_LIST_END_HASH() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · MOCKS_LIST_END() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · MOCKS_LIST_START() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · reset() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · SENTINEL_ANY_MOCKS() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MockContract · updateInvocationCount(bytes4,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ModuleManager · disableModule(address,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ModuleManager · enableModule(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ModuleManager · execTransactionFromModule(address,uint256,bytes,uint8) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ModuleManager · execTransactionFromModuleReturnData(address,uint256,bytes,uint8) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ModuleManager · getModulesPaginated(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ModuleManager · isModuleEnabled(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MultiSend · multiSend(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| MultiSendCallOnly · multiSend(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| OwnerManager · addOwnerWithThreshold(address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| OwnerManager · changeThreshold(uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| OwnerManager · getOwners() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| OwnerManager · getThreshold() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| OwnerManager · isOwner(address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| OwnerManager · removeOwner(address,address,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| OwnerManager · swapOwner(address,address,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ReentrancyTransactionGuard · checkAfterExecution(bytes32,bool) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ReentrancyTransactionGuard · checkTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes,address) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| ReentrancyTransactionGuard · supportsInterface(bytes4) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| SignMessageLib · getMessageHash(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| SignMessageLib · signMessage(bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| SimulateTxAccessor · simulate(address,uint256,bytes,uint8) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| StorageAccessible · getStorageAt(uint256,uint256) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| StorageAccessible · simulateAndRevert(address,bytes) · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| TestHandler · dudududu() · - · - · - · 0 · - │ +·································|·······································································································|·············|·············|·············|···············|··············· +| Deployments · · % of limit · │ +·········································································································································|·············|·············|·············|···············|··············· +| DelegateCallTransactionGuard · 283510 · 283522 · 283516 · 0.3 % · - │ +·········································································································································|·············|·············|·············|···············|··············· +| ERC1155Token · - · - · 525869 · 0.5 % · - │ +·········································································································································|·············|·············|·············|···············|··············· +| ERC20Token · - · - · 733462 · 0.7 % · - │ +·----------------------------------------------------------------------------------------------------------------------------------------|-------------|-------------|-------------|---------------|--------------· diff --git a/test/scripts/test_externalTests_parse_eth_gas_report.py b/test/scripts/test_externalTests_parse_eth_gas_report.py new file mode 100644 index 0000000000..cefa0487a2 --- /dev/null +++ b/test/scripts/test_externalTests_parse_eth_gas_report.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 + +from dataclasses import asdict +import unittest + +from textwrap import dedent + +from unittest_helpers import FIXTURE_DIR, load_fixture + +# 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 externalTests.parse_eth_gas_report import parse_report, ReportParsingError, ReportValidationError +# pragma pylint: enable=import-error + +ETH_GAS_REPORT_GNOSIS_RST_PATH = FIXTURE_DIR / 'eth_gas_report_gnosis.rst' +ETH_GAS_REPORT_GNOSIS_RST_CONTENT = load_fixture(ETH_GAS_REPORT_GNOSIS_RST_PATH) + + +class TestEthGasReport(unittest.TestCase): + def setUp(self): + self.maxDiff = 10000 + + def test_parse_report(self): + parsed_report = parse_report(ETH_GAS_REPORT_GNOSIS_RST_CONTENT) + + expected_report = { + 'solc_version': '0.8.10', + 'optimize': True, + 'runs': 200, + 'block_limit': 100000000, + 'total_method_gas': 57826 * 6 + 53900 * 2 + 51567 * 8 + 94816 * 85 + 201944 * 49 + 105568 * 52, + 'total_deployment_gas': 283516 + 525869 + 733462, + 'contracts': { + 'DelegateCallTransactionGuard': { + 'total_method_gas': 0, + 'min_deployment_gas': 283510, + 'max_deployment_gas': 283522, + 'avg_deployment_gas': 283516, + 'methods': None, + }, + 'ERC1155Token': { + 'total_method_gas': 57826 * 6 + 53900 * 2, + 'min_deployment_gas': None, + 'max_deployment_gas': None, + 'avg_deployment_gas': 525869, + 'methods': { + 'mint(address,uint256,uint256,bytes)': { + 'total_gas': 57826 * 6, + 'min_gas': 47934, + 'max_gas': 59804, + 'avg_gas': 57826, + 'call_count': 6 + }, + 'safeTransferFrom(address,address,uint256,uint256,bytes)': { + 'total_gas': 53900 * 2, + 'min_gas': 53900, + 'max_gas': 53900, + 'avg_gas': 53900, + 'call_count': 2, + }, + }, + }, + 'ERC20Token': { + 'total_method_gas': 51567 * 8, + 'min_deployment_gas': None, + 'max_deployment_gas': None, + 'avg_deployment_gas': 733462, + 'methods': { + 'transfer(address,uint256)': { + 'total_gas': 51567 * 8, + 'min_gas': 51567, + 'max_gas': 51567, + 'avg_gas': 51567, + 'call_count': 8, + }, + }, + }, + 'GnosisSafe': { + 'total_method_gas': 94816 * 85 + 201944 * 49, + 'min_deployment_gas': None, + 'max_deployment_gas': None, + 'avg_deployment_gas': None, + 'methods': { + 'execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)': { + 'total_gas': 94816 * 85, + 'min_gas': 59563, + 'max_gas': 151736, + 'avg_gas': 94816, + 'call_count': 85, + }, + 'setup(address[],uint256,address,bytes,address,address,uint256,address)': { + 'total_gas': 201944 * 49, + 'min_gas': 167642, + 'max_gas': 263690, + 'avg_gas': 201944, + 'call_count': 49, + }, + }, + }, + 'GnosisSafeProxyFactory': { + 'total_method_gas': 105568 * 52, + 'min_deployment_gas': None, + 'max_deployment_gas': None, + 'avg_deployment_gas': None, + 'methods': { + 'createProxy(address,bytes)': { + 'total_gas': 105568 * 52, + 'min_gas': 105568, + 'max_gas': 105580, + 'avg_gas': 105568, + 'call_count': 52, + }, + }, + }, + } + } + self.assertEqual(asdict(parsed_report), expected_report) + + def test_parse_report_should_fail_if_report_is_empty(self): + text_report = "" + with self.assertRaises(ReportValidationError) as manager: + parse_report(text_report) + self.assertEqual(str(manager.exception), "Report header not found.") + + def test_parse_report_should_fail_if_report_has_no_header(self): + text_report = dedent(""" + | Methods | + | ERC1155Token · mint() · 1 · 3 · 2 · 6 · - | + | Deployments · · % of limit · │ + | ERC1155Token · - · - · 5 · 1 % · - | + """).strip('\n') + with self.assertRaises(ReportValidationError) as manager: + parse_report(text_report) + self.assertEqual(str(manager.exception), "Report header not found.") + + def test_parse_report_should_fail_if_data_rows_have_no_headers(self): + text_report = dedent(""" + | ERC1155Token · mint() · 1 · 3 · 2 · 6 · - | + """).strip('\n') + expected_message = dedent(""" + Parsing error on line 1: Found data row without a section header. + | ERC1155Token | mint() | 1 | 3 | 2 | 6 | - | + """).strip('\n') + + with self.assertRaises(ReportParsingError) as manager: + parse_report(text_report) + self.assertEqual(str(manager.exception), expected_message) + + def test_parse_report_should_fail_if_report_has_more_than_one_header(self): + text_report = dedent(""" + | Solc version: 0.8.10 · Optimizer enabled: true · Runs: 200 · Block limit: 100000000 gas | + | Solc version: 0.8.9 · Optimizer enabled: false · Runs: 111 · Block limit: 999999999 gas | + """).strip('\n') + expected_message = dedent(""" + Parsing error on line 2: Duplicate report header. + | Solc version: 0.8.9 | Optimizer enabled: false | Runs: 111 | Block limit: 999999999 gas | + """).strip('\n') + + with self.assertRaises(ReportParsingError) as manager: + parse_report(text_report) + self.assertEqual(str(manager.exception), expected_message) + + def test_parse_report_should_fail_if_row_matching_same_method_call_appears_twice(self): + text_report = dedent(""" + | Methods | + | ERC1155Token · mint() · 47934 · 59804 · 57826 · 6 · - | + | ERC1155Token · mint() · 11111 · 22222 · 33333 · 4 · - | + """).strip('\n') + expected_message = dedent(""" + Parsing error on line 3: Duplicate method row for 'ERC1155Token.mint()'. + | ERC1155Token | mint() | 11111 | 22222 | 33333 | 4 | - | + """).strip('\n') + + with self.assertRaises(ReportParsingError) as manager: + parse_report(text_report) + self.assertEqual(str(manager.exception), expected_message) + + def test_parse_report_should_fail_if_row_matching_same_contract_deployment_appears_twice(self): + text_report = dedent(""" + | Deployments · · % of limit · │ + | ERC1155Token · - · - · 525869 · 0.5 % · - | + | ERC1155Token · - · - · 111111 · 0.6 % · - | + """).strip('\n') + expected_message = dedent(""" + Parsing error on line 3: Duplicate contract deployment row for 'ERC1155Token'. + | ERC1155Token | - | - | 111111 | 0.6 % | - | + """).strip('\n') + + with self.assertRaises(ReportParsingError) as manager: + parse_report(text_report) + self.assertEqual(str(manager.exception), expected_message) + + def test_parse_report_should_fail_if_method_row_appears_under_deployments_header(self): + text_report = dedent(""" + | Deployments · · % of limit · │ + | ERC1155Token · mint() · 47934 · 59804 · 57826 · 6 · - | + """).strip('\n') + expected_message = dedent(""" + Parsing error on line 2: Expected a table row with deployment details. + | ERC1155Token | mint() | 47934 | 59804 | 57826 | 6 | - | + """).strip('\n') + + with self.assertRaises(ReportParsingError) as manager: + parse_report(text_report) + self.assertEqual(str(manager.exception), expected_message) + + def test_parse_report_should_fail_if_deployment_row_appears_under_methods_header(self): + text_report = dedent(""" + | Methods | + | ERC1155Token · - · - · 525869 · 5 · - | + """).strip('\n') + expected_message = dedent(""" + Parsing error on line 2: Expected a table row with method details. + | ERC1155Token | - | - | 525869 | 5 | - | + """).strip('\n') + + with self.assertRaises(ReportParsingError) as manager: + parse_report(text_report) + self.assertEqual(str(manager.exception), expected_message) From c6094bb0c28a6735b0868ad9373c0240404db881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Sat, 18 Dec 2021 00:36:30 +0100 Subject: [PATCH 0368/1748] externalTests: Benchmark reports --- .circleci/config.yml | 9 ++ test/externalTests.sh | 32 ++--- test/externalTests/bleeps.sh | 6 +- test/externalTests/colony.sh | 3 + test/externalTests/common.sh | 166 +++++++++++++++++++++++-- test/externalTests/elementfi.sh | 3 + test/externalTests/ens.sh | 3 + test/externalTests/euler.sh | 3 + test/externalTests/gnosis-v2.sh | 4 + test/externalTests/gnosis.sh | 4 + test/externalTests/perpetual-pools.sh | 3 + test/externalTests/pool-together.sh | 3 + test/externalTests/prb-math.sh | 7 +- test/externalTests/trident.sh | 3 + test/externalTests/uniswap.sh | 4 + test/externalTests/yield-liquidator.sh | 3 + test/externalTests/zeppelin.sh | 3 + 17 files changed, 232 insertions(+), 27 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index af58d830f1..44837d8319 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1205,6 +1205,15 @@ jobs: name: External <> tests (native) command: | test/externalTests/<>.sh native /tmp/workspace/solc/solc + - store_artifacts: + path: reports/externalTests/ + # persist_to_workspace fails if the directory does not exist and the test script will create + # it only if it actually has benchmark results. + - run: mkdir -p reports/externalTests/ + - persist_to_workspace: + root: . + paths: + - reports/externalTests/ - gitter_notify_failure_unless_pr b_win: &b_win diff --git a/test/externalTests.sh b/test/externalTests.sh index a5e52c8524..b3b46460bf 100755 --- a/test/externalTests.sh +++ b/test/externalTests.sh @@ -28,26 +28,26 @@ set -e -REPO_ROOT="$(dirname "$0")" - source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/..") + verify_input "$@" printTask "Running external tests..." -"$REPO_ROOT/externalTests/zeppelin.sh" "$@" -"$REPO_ROOT/externalTests/gnosis.sh" "$@" -"$REPO_ROOT/externalTests/gnosis-v2.sh" "$@" -"$REPO_ROOT/externalTests/colony.sh" "$@" -"$REPO_ROOT/externalTests/ens.sh" "$@" -"$REPO_ROOT/externalTests/trident.sh" "$@" -"$REPO_ROOT/externalTests/euler.sh" "$@" -"$REPO_ROOT/externalTests/yield-liquidator.sh" "$@" -"$REPO_ROOT/externalTests/bleeps.sh" "$@" -"$REPO_ROOT/externalTests/pool-together.sh" "$@" -"$REPO_ROOT/externalTests/perpetual-pools.sh" "$@" -"$REPO_ROOT/externalTests/uniswap.sh" "$@" -"$REPO_ROOT/externalTests/prb-math.sh" "$@" -"$REPO_ROOT/externalTests/elementfi.sh" "$@" +"{$REPO_ROOT}/test/externalTests/zeppelin.sh" "$@" +"{$REPO_ROOT}/test/externalTests/gnosis.sh" "$@" +"{$REPO_ROOT}/test/externalTests/gnosis-v2.sh" "$@" +"{$REPO_ROOT}/test/externalTests/colony.sh" "$@" +"{$REPO_ROOT}/test/externalTests/ens.sh" "$@" +"{$REPO_ROOT}/test/externalTests/trident.sh" "$@" +"{$REPO_ROOT}/test/externalTests/euler.sh" "$@" +"{$REPO_ROOT}/test/externalTests/yield-liquidator.sh" "$@" +"{$REPO_ROOT}/test/externalTests/bleeps.sh" "$@" +"{$REPO_ROOT}/test/externalTests/pool-together.sh" "$@" +"{$REPO_ROOT}/test/externalTests/perpetual-pools.sh" "$@" +"{$REPO_ROOT}/test/externalTests/uniswap.sh" "$@" +"{$REPO_ROOT}/test/externalTests/prb-math.sh" "$@" +"{$REPO_ROOT}/test/externalTests/elementfi.sh" "$@" diff --git a/test/externalTests/bleeps.sh b/test/externalTests/bleeps.sh index 561200e219..bd3b0255b1 100755 --- a/test/externalTests/bleeps.sh +++ b/test/externalTests/bleeps.sh @@ -24,13 +24,16 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" SELECTED_PRESETS="$3" function compile_fn { npm run compile; } -function test_fn { npm run test; } +# NOTE: `npm run test` runs `mocha` which seems to disable the gas reporter. +function test_fn { HARDHAT_DEPLOY_FIXTURE=true npx --no hardhat --no-compile test; } function bleeps_test { @@ -87,6 +90,7 @@ function bleeps_test 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 bleeps "$repo" "$preset" done popd diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index d659899535..e23ce11350 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -73,6 +75,7 @@ function colony_test for preset in $SELECTED_PRESETS; do truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$preset" "${compile_only_presets[*]}" compile_fn test_fn + store_benchmark_report truffle colony "$repo" "$preset" done } diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index cd0afb8a49..8f7b09eb52 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -20,7 +20,7 @@ #------------------------------------------------------------------------------ set -e -# Requires "${REPO_ROOT}/scripts/common.sh" to be included before. +# Requires $REPO_ROOT to be defined and "${REPO_ROOT}/scripts/common.sh" to be included before. CURRENT_EVM_VERSION=london @@ -207,9 +207,19 @@ function force_truffle_compiler_settings echo "Compiler version (full): ${SOLCVERSION}" echo "-------------------------------------" - # Forcing the settings should always work by just overwriting the solc object. Forcing them by using a - # dedicated settings objects should only be the fallback. - echo "module.exports['compilers'] = $(truffle_compiler_settings "$solc_path" "$preset" "$evm_version");" >> "$config_file" + local compiler_settings gas_reporter_settings + compiler_settings=$(truffle_compiler_settings "$solc_path" "$preset" "$evm_version") + gas_reporter_settings=$(eth_gas_reporter_settings "$preset") + + { + echo "require('eth-gas-reporter');" + echo "module.exports['mocha'] = {" + echo " reporter: 'eth-gas-reporter'," + echo " reporterOptions: ${gas_reporter_settings}" + echo "};" + + echo "module.exports['compilers'] = ${compiler_settings};" + } >> "$config_file" } function name_hardhat_default_export @@ -278,16 +288,21 @@ function force_hardhat_compiler_settings echo "Compiler version (full): ${SOLCVERSION}" echo "-------------------------------------" - local settings - settings=$(hardhat_compiler_settings "$SOLCVERSION_SHORT" "$preset" "$evm_version") + local compiler_settings gas_reporter_settings + compiler_settings=$(hardhat_compiler_settings "$SOLCVERSION_SHORT" "$preset" "$evm_version") + gas_reporter_settings=$(eth_gas_reporter_settings "$preset") if [[ $config_file == *\.js ]]; then [[ $config_var_name == "" ]] || assertFail - echo "module.exports['solidity'] = ${settings}" >> "$config_file" + echo "require('hardhat-gas-reporter');" + echo "module.exports.gasReporter = ${gas_reporter_settings};" + echo "module.exports.solidity = ${compiler_settings};" else [[ $config_file == *\.ts ]] || assertFail [[ $config_var_name != "" ]] || assertFail - echo "${config_var_name}.solidity = {compilers: [${settings}]}" >> "$config_file" - fi + echo 'import "hardhat-gas-reporter";' + echo "${config_var_name}.gasReporter = ${gas_reporter_settings};" + echo "${config_var_name}.solidity = {compilers: [${compiler_settings}]};" + fi >> "$config_file" } function truffle_verify_compiler_version @@ -368,6 +383,21 @@ function replace_global_solc export PATH="$PWD:$PATH" } +function eth_gas_reporter_settings +{ + local preset="$1" + + echo "{" + echo " enabled: true," + echo " gasPrice: 1," # Gas price does not matter to us at all. Set to whatever to avoid API call. + echo " noColors: true," + echo " showTimeSpent: false," # We're not interested in test timing + echo " onlyCalledMethods: true," # Exclude entries with no gas for shorter report + echo " showMethodSig: true," # Should make diffs more stable if there are overloaded functions + echo " outputFile: \"$(gas_report_path "$preset")\"" + echo "}" +} + function truffle_compiler_settings { local solc_path="$1" @@ -495,3 +525,121 @@ function external_test rm -rf "$DIR" echo "Done." } + +function gas_report_path +{ + local preset="$1" + + echo "${DIR}/gas-report-${preset}.rst" +} + +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 bytecode_size_json_from_truffle_artifacts +{ + # NOTE: The output of this function is a series of concatenated JSON dicts rather than a list. + + for artifact in build/contracts/*.json; do + if [[ $(jq '. | has("unlinked_binary")' "$artifact") == false ]]; then + # Each artifact represents compilation output for a single contract. Some top-level keys contain + # bits of Standard JSON output while others are generated by Truffle. Process it into a dict + # of the form `{"": {"": }}`. + # NOTE: The `bytecode` field starts with 0x, which is why we subtract 1 from size. + jq '{ + (.ast.absolutePath): { + (.contractName): (.bytecode | length / 2 - 1) + } + }' "$artifact" + fi + done +} + +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" + done +} + +function combine_artifact_json +{ + # Combine all dicts into a list with `jq --slurp` and then use `reduce` to merge them into one + # big dict with keys of the form `":"`. Then run jq again to filter out items + # with zero size and put the rest under under a top-level `bytecode_size` key. Also add another + # key with total bytecode size. + # NOTE: The extra inner `bytecode_size` key is there only to make diffs more readable. + cat - | + jq --slurp 'reduce (.[] | to_entries[]) as {$key, $value} ({}; . + { + ($key + ":" + ($value | to_entries[].key)): { + bytecode_size: $value | to_entries[].value + } + })' | + jq --indent 4 --sort-keys '{ + bytecode_size: [. | to_entries[] | select(.value.bytecode_size > 0)] | from_entries, + total_bytecode_size: (reduce (. | to_entries[]) as {$key, $value} (0; . + $value.bytecode_size)) + }' +} + +function project_info_json +{ + local project_url="$1" + + echo "{" + echo " \"project\": {" + # NOTE: Given that we clone with `--depth 1`, we'll only get useful output out of `git describe` + # if we directly check out a tag. Still better than nothing. + echo " \"version\": \"$(git describe --always)\"," + echo " \"commit\": \"$(git rev-parse HEAD)\"," + echo " \"url\": \"${project_url}\"" + echo " }" + echo "}" +} + +function store_benchmark_report +{ + local framework="$1" + local project_name="$2" + local project_url="$3" + local preset="$4" + + [[ $framework == truffle || $framework == hardhat ]] || assertFail + [[ " ${AVAILABLE_PRESETS[*]} " == *" $preset "* ]] || assertFail + + local report_dir="${REPO_ROOT}/reports/externalTests" + local output_file="${report_dir}/benchmark-${project_name}-${preset}.json" + mkdir -p "$report_dir" + + { + if [[ -e $(gas_report_path "$preset") ]]; then + gas_report_to_json < "$(gas_report_path "$preset")" + fi + + "bytecode_size_json_from_${framework}_artifacts" | combine_artifact_json + project_info_json "$project_url" + } | jq --slurp "{\"${project_name}\": {\"${preset}\": add}}" --indent 4 --sort-keys > "$output_file" +} diff --git a/test/externalTests/elementfi.sh b/test/externalTests/elementfi.sh index f52a13ca67..3641eac2b4 100755 --- a/test/externalTests/elementfi.sh +++ b/test/externalTests/elementfi.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -96,6 +98,7 @@ function elementfi_test 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 elementfi "$repo" "$preset" done } diff --git a/test/externalTests/ens.sh b/test/externalTests/ens.sh index d3fcb0b13d..734c5d8ae8 100755 --- a/test/externalTests/ens.sh +++ b/test/externalTests/ens.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -68,6 +70,7 @@ function ens_test for preset in $SELECTED_PRESETS; do hardhat_run_test "$config_file" "$preset" "${compile_only_presets[*]}" compile_fn test_fn + store_benchmark_report hardhat ens "$repo" "$preset" done } diff --git a/test/externalTests/euler.sh b/test/externalTests/euler.sh index 485d7ae56a..b3b505051c 100755 --- a/test/externalTests/euler.sh +++ b/test/externalTests/euler.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -68,6 +70,7 @@ function euler_test for preset in $SELECTED_PRESETS; do hardhat_run_test "$config_file" "$preset" "${compile_only_presets[*]}" compile_fn test_fn + store_benchmark_report hardhat euler "$repo" "$preset" done } diff --git a/test/externalTests/gnosis-v2.sh b/test/externalTests/gnosis-v2.sh index a48dddf9c1..6b0915b6a0 100755 --- a/test/externalTests/gnosis-v2.sh +++ b/test/externalTests/gnosis-v2.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -65,12 +67,14 @@ function gnosis_safe_test neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$(first_word "$SELECTED_PRESETS")" npm install --package-lock + npm install eth-gas-reporter replace_version_pragmas [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc/dist" for preset in $SELECTED_PRESETS; do truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$preset" "${compile_only_presets[*]}" compile_fn test_fn + store_benchmark_report truffle gnosis2 "$repo" "$preset" done } diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index 1b430a9ae5..82d1892f2d 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -63,12 +65,14 @@ function gnosis_safe_test neutralize_package_json_hooks force_truffle_compiler_settings "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$(first_word "$SELECTED_PRESETS")" npm install --package-lock + npm install eth-gas-reporter replace_version_pragmas [[ $BINARY_TYPE == solcjs ]] && force_solc_modules "${DIR}/solc/dist" for preset in $SELECTED_PRESETS; do truffle_run_test "$config_file" "$BINARY_TYPE" "${DIR}/solc/dist" "$preset" "${compile_only_presets[*]}" compile_fn test_fn + store_benchmark_report truffle gnosis "$repo" "$preset" done } diff --git a/test/externalTests/perpetual-pools.sh b/test/externalTests/perpetual-pools.sh index e1ee9af8f5..8f90ed0b4d 100755 --- a/test/externalTests/perpetual-pools.sh +++ b/test/externalTests/perpetual-pools.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -68,6 +70,7 @@ function perpetual_pools_test 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 } diff --git a/test/externalTests/pool-together.sh b/test/externalTests/pool-together.sh index a7f5933c0e..b24cd6f4b2 100755 --- a/test/externalTests/pool-together.sh +++ b/test/externalTests/pool-together.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -72,6 +74,7 @@ function pool_together_test 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 pool-together "$repo" "$preset" done } diff --git a/test/externalTests/prb-math.sh b/test/externalTests/prb-math.sh index 53fad2c255..01bdb76f18 100755 --- a/test/externalTests/prb-math.sh +++ b/test/externalTests/prb-math.sh @@ -24,13 +24,16 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" SELECTED_PRESETS="$3" function compile_fn { yarn compile; } -function test_fn { yarn test; } +# NOTE: `yarn test` runs `mocha` which seems to disable the gas reporter. +function test_fn { npx --no hardhat --no-compile test; } function prb_math_test { @@ -70,11 +73,13 @@ function prb_math_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 --no-lock-file + yarn add hardhat-gas-reporter 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 prb-math "$repo" "$preset" done } diff --git a/test/externalTests/trident.sh b/test/externalTests/trident.sh index 8e6f35ae33..5e230560d5 100755 --- a/test/externalTests/trident.sh +++ b/test/externalTests/trident.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -92,6 +94,7 @@ function trident_test 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 trident "$repo" "$preset" done } diff --git a/test/externalTests/uniswap.sh b/test/externalTests/uniswap.sh index 96a5d2b63b..2f94c6abde 100755 --- a/test/externalTests/uniswap.sh +++ b/test/externalTests/uniswap.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -73,11 +75,13 @@ function uniswap_test yarn add @ethereumjs/tx@3.1.3 yarn install + yarn add hardhat-gas-reporter 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 uniswap "$repo" "$preset" done } diff --git a/test/externalTests/yield-liquidator.sh b/test/externalTests/yield-liquidator.sh index 6712941e74..1b5b9f1462 100755 --- a/test/externalTests/yield-liquidator.sh +++ b/test/externalTests/yield-liquidator.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -68,6 +70,7 @@ function yield_liquidator_test 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 yield_liquidator "$repo" "$preset" done } diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index d365dfe2a8..4094c69364 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -24,6 +24,8 @@ set -e source scripts/common.sh source test/externalTests/common.sh +REPO_ROOT=$(realpath "$(dirname "$0")/../..") + verify_input "$@" BINARY_TYPE="$1" BINARY_PATH="$2" @@ -66,6 +68,7 @@ function zeppelin_test 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" done } From 60d9aa0d4f34da1f0ccd022e69ca4c45f378ce20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 22 Dec 2021 17:45:20 +0100 Subject: [PATCH 0369/1748] Benchmark report collector job + summary --- .circleci/config.yml | 35 +++++++++++ scripts/externalTests/merge_benchmarks.sh | 60 +++++++++++++++++++ scripts/externalTests/summarize_benchmarks.sh | 53 ++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100755 scripts/externalTests/merge_benchmarks.sh create mode 100755 scripts/externalTests/summarize_benchmarks.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 44837d8319..a1fca20ceb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1216,6 +1216,23 @@ jobs: - reports/externalTests/ - gitter_notify_failure_unless_pr + c_ext_benchmarks: + <<: *base_node_small + steps: + - checkout + - attach_workspace: + at: . + - run: + name: Combine benchmark reports + command: cat reports/externalTests/benchmark-*.json | scripts/externalTests/merge_benchmarks.sh > reports/externalTests/all-benchmarks.json + - 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 + b_win: &b_win <<: *base_win_powershell_large steps: @@ -1466,6 +1483,24 @@ workflows: - t_ems_ext: *job_native_test_ext_prb_math - t_ems_ext: *job_native_test_ext_elementfi + - c_ext_benchmarks: + <<: *workflow_trigger_on_tags + requires: + - t_ems_compile_ext_colony + - t_native_compile_ext_gnosis + - t_native_test_ext_gnosis_v2 + - t_native_test_ext_zeppelin + - t_native_test_ext_ens + - t_native_test_ext_trident + - t_native_test_ext_euler + - t_native_test_ext_yield_liquidator + - t_native_test_ext_bleeps + - t_native_test_ext_pool_together + - t_native_test_ext_perpetual_pools + - t_native_test_ext_uniswap + - t_native_test_ext_prb_math + - t_native_test_ext_elementfi + # Windows build and tests - b_win: *workflow_trigger_on_tags - b_win_release: *workflow_trigger_on_tags diff --git a/scripts/externalTests/merge_benchmarks.sh b/scripts/externalTests/merge_benchmarks.sh new file mode 100755 index 0000000000..3e2d7318c7 --- /dev/null +++ b/scripts/externalTests/merge_benchmarks.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# ------------------------------------------------------------------------------ +# Reads multiple individual benchmark reports produced by scripts from +# test/externalTests/ from standard input and creates a combined report. +# +# Usage: +#