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 01/40] 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 b3a5f82e4..1ace4d5de 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 02/40] 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 1ace4d5de..6d70a0840 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 03/40] 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 6d70a0840..da5b2d2ef 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 04/40] 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 da5b2d2ef..6d9b0a3ba 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 1304da8af..59c29ca45 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 05/40] 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 0a90a2825..9aad572c8 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 b28e5c881ef2e0c2ab0666a56f386a400f976737 Mon Sep 17 00:00:00 2001 From: Midhun07 Date: Tue, 31 Aug 2021 22:27:09 +0530 Subject: [PATCH 06/40] Disallowed --error-recovery in Standard json, Assembly and Linker input modes --- Changelog.md | 1 + solc/CommandLineParser.cpp | 20 ++++++++++++----- test/solc/CommandLineParser.cpp | 39 ++++++++++++++------------------- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/Changelog.md b/Changelog.md index ddfe1648e..9aaf80f80 100644 --- a/Changelog.md +++ b/Changelog.md @@ -17,6 +17,7 @@ Bugfixes: * 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. * 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 IR Generator: Do not output empty switches/if-bodies for empty contracts. diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 89304ef3c..6b1fc1526 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -898,13 +898,21 @@ bool CommandLineParser::processArgs() else m_options.input.mode = InputMode::Compiler; - if ( - m_args.count(g_strExperimentalViaIR) > 0 && - m_options.input.mode != InputMode::Compiler && - m_options.input.mode != InputMode::CompilerWithASTImport - ) + map> validOptionInputModeCombinations = { + // TODO: This should eventually contain all options. + {g_strErrorRecovery, {InputMode::Compiler, InputMode::CompilerWithASTImport}}, + {g_strExperimentalViaIR, {InputMode::Compiler, InputMode::CompilerWithASTImport}}, + }; + vector invalidOptionsForCurrentInputMode; + for (auto const& [optionName, inputModes]: validOptionInputModeCombinations) { - serr() << "The option --" << g_strExperimentalViaIR << " is only supported in the compiler mode." << endl; + if (m_args.count(optionName) > 0 && inputModes.count(m_options.input.mode) == 0) + invalidOptionsForCurrentInputMode.push_back(optionName); + } + + if (!invalidOptionsForCurrentInputMode.empty()) + { + serr() << "The following options are not supported in the current input mode: " << joinOptionNames(invalidOptionsForCurrentInputMode) << endl; return false; } diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index f2e4ea387..3b2998ce1 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -267,7 +267,6 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options) "--include-path=/home/user/include", "--allow-paths=/tmp,/home,project,../contracts", "--ignore-missing", - "--error-recovery", // Ignored in assembly mode "--overwrite", "--evm-version=spuriousDragon", "--revert-strings=strip", // Accepted but has no effect in assembly mode @@ -356,7 +355,6 @@ BOOST_AUTO_TEST_CASE(standard_json_mode_options) "--include-path=/home/user/include", "--allow-paths=/tmp,/home,project,../contracts", "--ignore-missing", - "--error-recovery", // Ignored in Standard JSON mode "--output-dir=/tmp/out", // Accepted but has no effect in Standard JSON mode "--overwrite", // Accepted but has no effect in Standard JSON mode "--evm-version=spuriousDragon", // Ignored in Standard JSON mode @@ -413,30 +411,25 @@ BOOST_AUTO_TEST_CASE(standard_json_mode_options) BOOST_TEST(parsedOptions.value() == expectedOptions); } -BOOST_AUTO_TEST_CASE(experimental_via_ir_invalid_input_modes) +BOOST_AUTO_TEST_CASE(invalid_options_input_modes_combinations) { - static array const inputModeOptions = { - "--assemble", - "--yul", - "--strict-assembly", - "--standard-json", - "--link", + map> invalidOptionInputModeCombinations = { + // TODO: This should eventually contain all options. + {"--error-recovery", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}}, + {"--experimental-via-ir", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}} }; - for (string const& inputModeOption: inputModeOptions) - { - stringstream sout, serr; - vector commandLine = { - "solc", - "--experimental-via-ir", - "file", - inputModeOption, - }; - optional parsedOptions = parseCommandLine(commandLine, sout, serr); - BOOST_TEST(sout.str() == ""); - BOOST_TEST(serr.str() == "The option --experimental-via-ir is only supported in the compiler mode.\n"); - BOOST_REQUIRE(!parsedOptions.has_value()); - } + for (auto const& [optionName, inputModes]: invalidOptionInputModeCombinations) + for (string const& inputMode: inputModes) + { + stringstream sout, serr; + vector commandLine = {"solc", optionName, "file", inputMode}; + optional parsedOptions = parseCommandLine(commandLine, sout, 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()); + } } BOOST_AUTO_TEST_SUITE_END() From 9f48b7419ccc31dd1239933d916eb3b23e55481d Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 14 Oct 2021 16:18:20 +0200 Subject: [PATCH 07/40] 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 ddfe1648e..8e1a2d55f 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 5c7865c01..6ef142906 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 38eecc245..531fd1b92 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 8a605b472..bad9a357f 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 @@ public: BuiltinContext& _builtinContext, bool _allowStackOpt = false, ExternalIdentifierAccess::CodeGenerator const& _identifierAccessCodeGen = {}, - bool _useNamedLabelsForFunctions = false + UseNamedLabels _useNamedLabelsForFunctions = UseNamedLabels::Never ): CodeTransform( _assembly, _analysisInfo, @@ -108,7 +112,7 @@ protected: 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 @@ private: 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 a526bf218..e41a68387 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 000000000..4299d023e --- /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 000000000..5284ffe5c --- /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 000000000..55032c56e --- /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 000000000..00192f8f4 --- /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 000000000..903cc6eb4 --- /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 000000000..014a1178f --- /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 000000000..0ede2d25e --- /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 000000000..8a7bec790 --- /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 000000000..2c89c24e0 --- /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 000000000..014a1178f --- /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 000000000..e27ca014a --- /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 000000000..f3dc84340 --- /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 000000000..21fbdb28a --- /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 816d8021e4f57b1b32eb3ce1fbfa421a585a0f0f Mon Sep 17 00:00:00 2001 From: soroosh-sdi Date: Fri, 1 Oct 2021 09:18:52 +0330 Subject: [PATCH 08/40] Remove linking to unqualified library name - SemanticTests accepts fully qualified library name and also unqualifed library name when the library is defined in the same file for convenience. - commandline tests are added! Signed-off-by: soroosh-sdi --- Changelog.md | 2 +- libevmasm/LinkerObject.cpp | 8 ---- .../linking_qualified_library_name/args | 1 + .../contract1.sol | 10 ++++ .../linking_qualified_library_name/math.sol | 6 +++ .../linking_qualified_library_name/output | 8 ++++ .../output | 26 ---------- .../args | 1 + .../err | 0 .../input.yul | 6 +++ .../output | 21 ++++++++ .../args | 1 + .../err | 1 + .../input.yul | 0 .../output | 21 ++++++++ .../args | 2 +- .../err | 1 + .../input.yul | 6 +++ .../output | 21 ++++++++ .../args | 1 + .../err | 1 + .../input.yul | 6 +++ .../output | 21 ++++++++ .../linking_unqualified_library_name/args | 1 + .../contract1.sol | 11 +++++ .../contract2.sol | 10 ++++ .../error.sol | 6 +++ .../linking_unqualified_library_name/math.sol | 6 +++ .../linking_unqualified_library_name/output | 20 ++++++++ test/libsolidity/SemanticTest.cpp | 9 +++- test/libsolidity/SolidityEndToEndTest.cpp | 48 +++++++++---------- .../libraries/library_address_via_module.sol | 2 +- test/libsolidity/util/TestFileParser.cpp | 22 ++++++++- 33 files changed, 242 insertions(+), 64 deletions(-) create mode 100644 test/cmdlineTests/linking_qualified_library_name/args create mode 100644 test/cmdlineTests/linking_qualified_library_name/contract1.sol create mode 100644 test/cmdlineTests/linking_qualified_library_name/math.sol create mode 100644 test/cmdlineTests/linking_qualified_library_name/output delete mode 100644 test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/output create mode 100644 test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/args rename test/cmdlineTests/{linking_strict_assembly_no_file_name_in_link_reference => linking_strict_assembly_qualified_library_qualified_reference}/err (100%) create mode 100644 test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/input.yul create mode 100644 test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output create mode 100644 test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/args create mode 100644 test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/err rename test/cmdlineTests/{linking_strict_assembly_no_file_name_in_link_reference => linking_strict_assembly_qualified_library_unqualified_reference}/input.yul (100%) create mode 100644 test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output rename test/cmdlineTests/{linking_strict_assembly_no_file_name_in_link_reference => linking_strict_assembly_unqualified_library_qualified_reference}/args (68%) create mode 100644 test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/err create mode 100644 test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/input.yul create mode 100644 test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output create mode 100644 test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/args create mode 100644 test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/err create mode 100644 test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/input.yul create mode 100644 test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output create mode 100644 test/cmdlineTests/linking_unqualified_library_name/args create mode 100644 test/cmdlineTests/linking_unqualified_library_name/contract1.sol create mode 100644 test/cmdlineTests/linking_unqualified_library_name/contract2.sol create mode 100644 test/cmdlineTests/linking_unqualified_library_name/error.sol create mode 100644 test/cmdlineTests/linking_unqualified_library_name/math.sol create mode 100644 test/cmdlineTests/linking_unqualified_library_name/output diff --git a/Changelog.md b/Changelog.md index ddfe1648e..60a62a402 100644 --- a/Changelog.md +++ b/Changelog.md @@ -20,7 +20,7 @@ Bugfixes: * 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 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. diff --git a/libevmasm/LinkerObject.cpp b/libevmasm/LinkerObject.cpp index fdb9a460f..07e34acab 100644 --- a/libevmasm/LinkerObject.cpp +++ b/libevmasm/LinkerObject.cpp @@ -73,14 +73,6 @@ LinkerObject::matchLibrary( ) { auto it = _libraryAddresses.find(_linkRefName); - if (it != _libraryAddresses.end()) - return &it->second; - // If the user did not supply a fully qualified library name, - // try to match only the simple library name - size_t colon = _linkRefName.find(':'); - if (colon == string::npos) - return nullptr; - it = _libraryAddresses.find(_linkRefName.substr(colon + 1)); if (it != _libraryAddresses.end()) return &it->second; return nullptr; diff --git a/test/cmdlineTests/linking_qualified_library_name/args b/test/cmdlineTests/linking_qualified_library_name/args new file mode 100644 index 000000000..dc996f46e --- /dev/null +++ b/test/cmdlineTests/linking_qualified_library_name/args @@ -0,0 +1 @@ +linking_qualified_library_name/contract1.sol --bin --libraries linking_qualified_library_name/math.sol:Log:0x7777777777777777777777777777777777777777 diff --git a/test/cmdlineTests/linking_qualified_library_name/contract1.sol b/test/cmdlineTests/linking_qualified_library_name/contract1.sol new file mode 100644 index 000000000..aedea65fa --- /dev/null +++ b/test/cmdlineTests/linking_qualified_library_name/contract1.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +import "linking_qualified_library_name/math.sol"; + +contract C { + function foo() public { + Log.log10(); + } +} diff --git a/test/cmdlineTests/linking_qualified_library_name/math.sol b/test/cmdlineTests/linking_qualified_library_name/math.sol new file mode 100644 index 000000000..62f00ec34 --- /dev/null +++ b/test/cmdlineTests/linking_qualified_library_name/math.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +library Log { + function log10() external {} +} diff --git a/test/cmdlineTests/linking_qualified_library_name/output b/test/cmdlineTests/linking_qualified_library_name/output new file mode 100644 index 000000000..834874bf8 --- /dev/null +++ b/test/cmdlineTests/linking_qualified_library_name/output @@ -0,0 +1,8 @@ + +======= linking_qualified_library_name/contract1.sol:C ======= +Binary: + + +======= linking_qualified_library_name/math.sol:Log ======= +Binary: + diff --git a/test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/output b/test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/output deleted file mode 100644 index 5d5b87c67..000000000 --- a/test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/output +++ /dev/null @@ -1,26 +0,0 @@ - -======= linking_strict_assembly_no_file_name_in_link_reference/input.yul (EVM) ======= - -Pretty printed source: -object "a" { - code { - let addr := linkersymbol("L") - sstore(0, addr) - } -} - - -Binary representation: -7312345678901234567890123456789012345678908060005550 - -Text representation: - /* "linking_strict_assembly_no_file_name_in_link_reference/input.yul":44:61 */ - linkerSymbol("8aa64f937099b65a4febc243a5ae0f2d6416bb9e473c30dd29c1ee498fb7c5a8") - /* "linking_strict_assembly_no_file_name_in_link_reference/input.yul":80:84 */ - dup1 - /* "linking_strict_assembly_no_file_name_in_link_reference/input.yul":77:78 */ - 0x00 - /* "linking_strict_assembly_no_file_name_in_link_reference/input.yul":70:85 */ - sstore - /* "linking_strict_assembly_no_file_name_in_link_reference/input.yul":22:91 */ - pop diff --git a/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/args b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/args new file mode 100644 index 000000000..1c8721f24 --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/args @@ -0,0 +1 @@ +--strict-assembly --libraries :L=0x1234567890123456789012345678901234567890 --debug-info none diff --git a/test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/err b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/err similarity index 100% rename from test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/err rename to test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/err diff --git a/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/input.yul b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/input.yul new file mode 100644 index 000000000..e5c134b87 --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/input.yul @@ -0,0 +1,6 @@ +object "a" { + code { + let addr := linkersymbol(":L") + sstore(0, addr) + } +} diff --git a/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output new file mode 100644 index 000000000..261856e96 --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output @@ -0,0 +1,21 @@ + +======= linking_strict_assembly_qualified_library_qualified_reference/input.yul (EVM) ======= + +Pretty printed source: +object "a" { + code { + let addr := linkersymbol(":L") + sstore(0, addr) + } +} + + +Binary representation: +7312345678901234567890123456789012345678908060005550 + +Text representation: + linkerSymbol("20a18a9bf97d889dcf77111b674da319a4e9e3e05d3f4df9e0bf5c588dd4f0f8") + dup1 + 0x00 + sstore + pop diff --git a/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/args b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/args new file mode 100644 index 000000000..1c8721f24 --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/args @@ -0,0 +1 @@ +--strict-assembly --libraries :L=0x1234567890123456789012345678901234567890 --debug-info none diff --git a/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/err b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/input.yul b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/input.yul similarity index 100% rename from test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/input.yul rename to test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/input.yul diff --git a/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output new file mode 100644 index 000000000..84204264d --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output @@ -0,0 +1,21 @@ + +======= linking_strict_assembly_qualified_library_unqualified_reference/input.yul (EVM) ======= + +Pretty printed source: +object "a" { + code { + let addr := linkersymbol("L") + sstore(0, addr) + } +} + + +Binary representation: +73__$8aa64f937099b65a4febc243a5ae0f2d64$__8060005550 + +Text representation: + linkerSymbol("8aa64f937099b65a4febc243a5ae0f2d6416bb9e473c30dd29c1ee498fb7c5a8") + dup1 + 0x00 + sstore + pop diff --git a/test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/args b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/args similarity index 68% rename from test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/args rename to test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/args index c7de26a69..c8299b9b6 100644 --- a/test/cmdlineTests/linking_strict_assembly_no_file_name_in_link_reference/args +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/args @@ -1 +1 @@ ---strict-assembly --libraries L=0x1234567890123456789012345678901234567890 +--strict-assembly --libraries L=0x1234567890123456789012345678901234567890 --debug-info none diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/err b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/input.yul b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/input.yul new file mode 100644 index 000000000..e5c134b87 --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/input.yul @@ -0,0 +1,6 @@ +object "a" { + code { + let addr := linkersymbol(":L") + sstore(0, addr) + } +} diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output new file mode 100644 index 000000000..e7dc14542 --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output @@ -0,0 +1,21 @@ + +======= linking_strict_assembly_unqualified_library_qualified_reference/input.yul (EVM) ======= + +Pretty printed source: +object "a" { + code { + let addr := linkersymbol(":L") + sstore(0, addr) + } +} + + +Binary representation: +73__$20a18a9bf97d889dcf77111b674da319a4$__8060005550 + +Text representation: + linkerSymbol("20a18a9bf97d889dcf77111b674da319a4e9e3e05d3f4df9e0bf5c588dd4f0f8") + dup1 + 0x00 + sstore + pop diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/args b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/args new file mode 100644 index 000000000..c8299b9b6 --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/args @@ -0,0 +1 @@ +--strict-assembly --libraries L=0x1234567890123456789012345678901234567890 --debug-info none diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/err b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/err new file mode 100644 index 000000000..014a1178f --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/err @@ -0,0 +1 @@ +Warning: Yul is still experimental. Please use the output with care. diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/input.yul b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/input.yul new file mode 100644 index 000000000..fcfab5bcf --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/input.yul @@ -0,0 +1,6 @@ +object "a" { + code { + let addr := linkersymbol("L") + sstore(0, addr) + } +} diff --git a/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output new file mode 100644 index 000000000..103b67e2e --- /dev/null +++ b/test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output @@ -0,0 +1,21 @@ + +======= linking_strict_assembly_unqualified_library_unqualified_reference/input.yul (EVM) ======= + +Pretty printed source: +object "a" { + code { + let addr := linkersymbol("L") + sstore(0, addr) + } +} + + +Binary representation: +7312345678901234567890123456789012345678908060005550 + +Text representation: + linkerSymbol("8aa64f937099b65a4febc243a5ae0f2d6416bb9e473c30dd29c1ee498fb7c5a8") + dup1 + 0x00 + sstore + pop diff --git a/test/cmdlineTests/linking_unqualified_library_name/args b/test/cmdlineTests/linking_unqualified_library_name/args new file mode 100644 index 000000000..6118acf02 --- /dev/null +++ b/test/cmdlineTests/linking_unqualified_library_name/args @@ -0,0 +1 @@ +linking_unqualified_library_name/contract1.sol linking_unqualified_library_name/contract2.sol --bin --libraries Log:0x7777777777777777777777777777777777777777 diff --git a/test/cmdlineTests/linking_unqualified_library_name/contract1.sol b/test/cmdlineTests/linking_unqualified_library_name/contract1.sol new file mode 100644 index 000000000..38e43f9d4 --- /dev/null +++ b/test/cmdlineTests/linking_unqualified_library_name/contract1.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + + +import "linking_unqualified_library_name/error.sol"; + +contract C { + function foo() public { + Log.print(); + } +} diff --git a/test/cmdlineTests/linking_unqualified_library_name/contract2.sol b/test/cmdlineTests/linking_unqualified_library_name/contract2.sol new file mode 100644 index 000000000..6ddb8ad6e --- /dev/null +++ b/test/cmdlineTests/linking_unqualified_library_name/contract2.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +import "linking_unqualified_library_name/math.sol"; + +contract C { + function foo() public { + Log.log10(); + } +} diff --git a/test/cmdlineTests/linking_unqualified_library_name/error.sol b/test/cmdlineTests/linking_unqualified_library_name/error.sol new file mode 100644 index 000000000..ec29bda35 --- /dev/null +++ b/test/cmdlineTests/linking_unqualified_library_name/error.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +library Log { + function print() external {} +} diff --git a/test/cmdlineTests/linking_unqualified_library_name/math.sol b/test/cmdlineTests/linking_unqualified_library_name/math.sol new file mode 100644 index 000000000..62f00ec34 --- /dev/null +++ b/test/cmdlineTests/linking_unqualified_library_name/math.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; + +library Log { + function log10() external {} +} diff --git a/test/cmdlineTests/linking_unqualified_library_name/output b/test/cmdlineTests/linking_unqualified_library_name/output new file mode 100644 index 000000000..be64a93c9 --- /dev/null +++ b/test/cmdlineTests/linking_unqualified_library_name/output @@ -0,0 +1,20 @@ + +======= linking_unqualified_library_name/contract1.sol:C ======= +Binary: +__$cdf6d5ab08a9335b02e7c2475aa27d04fa$__ + +// $cdf6d5ab08a9335b02e7c2475aa27d04fa$ -> linking_unqualified_library_name/error.sol:Log + +======= linking_unqualified_library_name/contract2.sol:C ======= +Binary: +__$22584241c2fc4f2884d5222245463779a8$__ + +// $22584241c2fc4f2884d5222245463779a8$ -> linking_unqualified_library_name/math.sol:Log + +======= linking_unqualified_library_name/error.sol:Log ======= +Binary: + + +======= linking_unqualified_library_name/math.sol:Log ======= +Binary: + diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 56e1b1a8b..c5ee04044 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include using namespace std; @@ -383,7 +384,13 @@ TestCase::TestResult SemanticTest::runTest( soltestAssert( deploy(test.call().signature, 0, {}, libraries) && m_transactionSuccessful, "Failed to deploy library " + test.call().signature); - libraries[test.call().signature] = m_contractAddress; + // For convenience, in semantic tests we assume that an unqualified name like `L` is equivalent to one + // with an empty source unit name (`:L`). This is fine because the compiler never uses unqualified + // names in the Yul code it produces and does not allow `linkersymbol()` at all in inline assembly. + if (test.call().signature.find(':') == string::npos) + libraries[":" + test.call().signature] = m_contractAddress; + else + libraries[test.call().signature] = m_contractAddress; continue; } else diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index e724f9998..e5a6b8cf7 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1565,7 +1565,7 @@ BOOST_AUTO_TEST_CASE(library_call_in_homestead) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs()); ABI_CHECK(callContractFunction("sender()"), encodeArgs(m_sender)); ) @@ -1598,7 +1598,7 @@ BOOST_AUTO_TEST_CASE(library_call_protection) ABI_CHECK(callContractFunction("np(Lib.S storage)", 0), encodeArgs()); ABI_CHECK(callContractFunction("v(Lib.S storage)", 0), encodeArgs(m_sender)); ABI_CHECK(callContractFunction("pu()"), encodeArgs(2)); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); ABI_CHECK(callContractFunction("s()"), encodeArgs(0)); ABI_CHECK(callContractFunction("np()"), encodeArgs(m_sender)); ABI_CHECK(callContractFunction("s()"), encodeArgs(3)); @@ -1627,7 +1627,7 @@ BOOST_AUTO_TEST_CASE(library_staticcall_delegatecall) } )"; compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs(1)); } @@ -1883,7 +1883,7 @@ BOOST_AUTO_TEST_CASE(struct_referencing) compileAndRun(sourceCode, 0, "L"); ABI_CHECK(callContractFunction("f()"), encodeArgs(0, 3)); ABI_CHECK(callContractFunction("g()"), encodeArgs(4)); - compileAndRun(sourceCode, 0, "C", bytes(), map{ {"L", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{ {":L", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs(1)); ABI_CHECK(callContractFunction("g()"), encodeArgs(2)); ABI_CHECK(callContractFunction("h()"), encodeArgs(0, 5)); @@ -1932,7 +1932,7 @@ BOOST_AUTO_TEST_CASE(enum_referencing) compileAndRun(sourceCode, 0, "L"); ABI_CHECK(callContractFunction("f()"), encodeArgs(1)); ABI_CHECK(callContractFunction("g()"), encodeArgs(3)); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"L", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":L", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs(3)); ABI_CHECK(callContractFunction("g()"), encodeArgs(3)); ABI_CHECK(callContractFunction("h()"), encodeArgs(1)); @@ -2763,7 +2763,7 @@ BOOST_AUTO_TEST_CASE(library_call) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); ABI_CHECK(callContractFunction("f(uint256)", u256(33)), encodeArgs(u256(33) * 9)); ) } @@ -2781,7 +2781,7 @@ BOOST_AUTO_TEST_CASE(library_function_external) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); ABI_CHECK(callContractFunction("f(bytes)", u256(0x20), u256(5), "abcde"), encodeArgs("c")); ) } @@ -2801,7 +2801,7 @@ BOOST_AUTO_TEST_CASE(library_stray_values) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); ABI_CHECK(callContractFunction("f(uint256)", u256(33)), encodeArgs(u256(42))); ) } @@ -2834,7 +2834,7 @@ BOOST_AUTO_TEST_CASE(internal_types_in_library) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(4), u256(17))); ) } @@ -2868,7 +2868,7 @@ BOOST_AUTO_TEST_CASE(mapping_arguments_in_library) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + 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))); @@ -2919,7 +2919,7 @@ BOOST_AUTO_TEST_CASE(mapping_returns_in_library) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + 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))); @@ -2998,7 +2998,7 @@ BOOST_AUTO_TEST_CASE(mapping_returns_in_library_named) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + 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))); ) @@ -3029,7 +3029,7 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_public) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + 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))); ) } @@ -3065,7 +3065,7 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_external) { string prefix = "pragma abicoder " + string(v2 ? "v2" : "v1") + ";\n"; compileAndRun(prefix + libSourceCode, 0, "Lib"); - compileAndRun(prefix + sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(prefix + sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(2), u256(0), u256(84), u256(46), u256(0), u256(198))); } } @@ -3093,7 +3093,7 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_return) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + 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))); ) } @@ -3124,7 +3124,7 @@ BOOST_AUTO_TEST_CASE(using_library_structs) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7), u256(8))); ) } @@ -3340,7 +3340,7 @@ BOOST_AUTO_TEST_CASE(using_for_function_on_struct) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + 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))); ) @@ -3366,7 +3366,7 @@ BOOST_AUTO_TEST_CASE(using_for_overload) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + 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))); ) @@ -3388,7 +3388,7 @@ BOOST_AUTO_TEST_CASE(using_for_by_name) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + 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))); ) @@ -3411,7 +3411,7 @@ BOOST_AUTO_TEST_CASE(bound_function_in_function) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "L"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"L", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":L", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7))); ) } @@ -3432,7 +3432,7 @@ BOOST_AUTO_TEST_CASE(bound_function_in_var) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + 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))); ) @@ -3458,7 +3458,7 @@ BOOST_AUTO_TEST_CASE(bound_function_to_string) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(3))); ABI_CHECK(callContractFunction("g()"), encodeArgs(u256(3))); ) @@ -3631,7 +3631,7 @@ BOOST_AUTO_TEST_CASE(payable_function_calls_library) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "L"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"L", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":L", m_contractAddress}}); ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs(u256(7))); ) } @@ -4720,7 +4720,7 @@ BOOST_AUTO_TEST_CASE(event_wrong_abi_name) ALSO_VIA_YUL( DISABLE_EWASM_TESTRUN() compileAndRun(sourceCode, 0, "ClientReceipt", bytes()); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"ClientReceipt", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":ClientReceipt", m_contractAddress}}); callContractFunction("f()"); BOOST_REQUIRE_EQUAL(numLogs(), 1); diff --git a/test/libsolidity/semanticTests/libraries/library_address_via_module.sol b/test/libsolidity/semanticTests/libraries/library_address_via_module.sol index ca7c9c271..effcd13c8 100644 --- a/test/libsolidity/semanticTests/libraries/library_address_via_module.sol +++ b/test/libsolidity/semanticTests/libraries/library_address_via_module.sol @@ -42,7 +42,7 @@ contract C { // EVMVersion: >=byzantium // compileViaYul: also // ---- -// library: L +// library: "a.sol":L // addr() -> false // g(uint256): 1 -> 1 // g(uint256): 2 -> 4 diff --git a/test/libsolidity/util/TestFileParser.cpp b/test/libsolidity/util/TestFileParser.cpp index 65a7e9c0f..6652f704a 100644 --- a/test/libsolidity/util/TestFileParser.cpp +++ b/test/libsolidity/util/TestFileParser.cpp @@ -100,8 +100,26 @@ vector TestFileParser::parseFunctionCall if (accept(Token::Library, true)) { expect(Token::Colon); - call.signature = m_scanner.currentLiteral(); - expect(Token::Identifier); + string libraryName; + if (accept(Token::String)) + { + libraryName = m_scanner.currentLiteral(); + expect(Token::String); + expect(Token::Colon); + libraryName += ':' + m_scanner.currentLiteral(); + expect(Token::Identifier); + } + else if (accept(Token::Colon, true)) + { + libraryName = ':' + m_scanner.currentLiteral(); + expect(Token::Identifier); + } + else + { + libraryName = m_scanner.currentLiteral(); + expect(Token::Identifier); + } + call.signature = libraryName; call.kind = FunctionCall::Kind::Library; call.expectations.failure = false; } From 2278673936f6f5aa8a243443d66680c9f6a9be0e Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 19 Oct 2021 10:54:54 -0400 Subject: [PATCH 09/40] Fix formatting --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index fadc252fc..a7bfbbe44 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 10/40] 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 a859b8464..266218baf 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 11/40] 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 8afbc58c3..fb971410a 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 12/40] 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 a859b8464..d086c672b 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 13/40] 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 a859b8464..73f658b1e 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 14/40] 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 73f658b1e..1c359ac81 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 15/40] 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 1de35cf6b..49e66537d 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 16/40] 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 69c3573fc..2ab1bb037 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 34aa69803..a410a9863 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 6946ff463..0c8f03cb9 100644 --- a/liblangutil/Exceptions.h +++ b/liblangutil/Exceptions.h @@ -258,6 +258,8 @@ public: 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 623e13dd1..0edd551b8 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 5bac03a9a..e18400b60 100644 --- a/liblangutil/SourceReferenceFormatter.h +++ b/liblangutil/SourceReferenceFormatter.h @@ -87,7 +87,7 @@ public: 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 17/40] 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 7344d1291..00c7223d5 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 18/40] 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 02487034a..f99247b32 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 6f91f0713..67fc76e83 100644 --- a/liblangutil/ErrorReporter.h +++ b/liblangutil/ErrorReporter.h @@ -72,6 +72,8 @@ public: 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 886720568..fd91b87dc 100644 --- a/liblangutil/UniqueErrorReporter.h +++ b/liblangutil/UniqueErrorReporter.h @@ -61,6 +61,20 @@ public: 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 19/40] 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 48fdbd328..630eb0619 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 460895e3b..a7dfb7692 100644 --- a/libsmtutil/CHCSmtLib2Interface.h +++ b/libsmtutil/CHCSmtLib2Interface.h @@ -44,7 +44,9 @@ public: 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 203255345..8385c1c40 100644 --- a/libsmtutil/CHCSolverInterface.h +++ b/libsmtutil/CHCSolverInterface.h @@ -54,8 +54,8 @@ public: }; /// 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 1196b27ff..82dca4878 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 a0e4bfa67..5a768f65c 100644 --- a/libsmtutil/Z3CHCInterface.h +++ b/libsmtutil/Z3CHCInterface.h @@ -43,7 +43,7 @@ public: 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 20/40] 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 87ee78013..ca4c497de 100644 --- a/libsmtutil/SolverInterface.h +++ b/libsmtutil/SolverInterface.h @@ -23,7 +23,9 @@ #include #include +#include +#include #include #include @@ -305,6 +307,64 @@ public: ); } + 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 03105a172..3a5c75bf3 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 21/40] 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 000000000..2591328f8 --- /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 000000000..3efbeb781 --- /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 22/40] 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 23aa7590e..6e0eb4f3b 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 7357c9beb..16af42f45 100644 --- a/libsolidity/formal/Predicate.h +++ b/libsolidity/formal/Predicate.h @@ -21,6 +21,8 @@ #include #include +#include + #include #include @@ -143,6 +145,9 @@ public: /// @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 @@ public: /// @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 @@ private: 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 23/40] 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 000000000..9dad0722c --- /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 000000000..b6459fccd --- /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 24/40] 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 207894d39..8fe3a2120 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 a01985fcb..5623b2a19 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 25/40] 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 a1cb68c35..7e3791eab 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 f0072313b..b75a975df 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 24b27c55b..d9e27a89c 100644 --- a/libsolidity/formal/CHC.h +++ b/libsolidity/formal/CHC.h @@ -245,9 +245,9 @@ private: //@{ /// 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 @@ private: 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 26/40] 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 b75a975df..bfdb0b428 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 8fe3a2120..274571a15 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 5623b2a19..3d137044a 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 27/40] 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 66f5dc4e5..da28cf29f 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 6b1fc1526..22d92d463 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 28/40] 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 3d137044a..e3e93fcf4 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 5606b0bfe..3b6b8e1b8 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 9cc4e5751..54d23c74f 100644 --- a/test/libsolidity/SMTCheckerTest.h +++ b/test/libsolidity/SMTCheckerTest.h @@ -49,6 +49,8 @@ protected: 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 29/40] 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 9290211a2..fe9c73b04 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 30/40] 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 3b2998ce1..663bf022c 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 332b9fc04..82066bf52 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 31/40] 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 55b2160c4..5ed512278 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 4796e3a81..294038399 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 5ad65991a..468f34257 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 c6e695f24..48e0f73bf 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 3ab218741..833caa24f 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 cd9b6690d..71571d944 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 a51c7aa7d..c96d53047 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 5756c7aff..4f1cf701b 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 525c704e1..66dad8412 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 086224a11..0023906fe 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 78a020e05..caafcbd39 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 f4d5c889c..062b668c3 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 5920a4e74..30f194eb7 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 6b23ac1d4..ad3ba7823 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 0a440e7a4..930736ce8 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 6992ca1e4..9cc3f2e37 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 1b241745a..60b11c91a 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 c29c34f62..dcda253ce 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 43eebddcf..87b9d92bf 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 100f11066..f88eab0bf 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 ea5947d01..fc4719cef 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 c561179ec..c4714e2e3 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 183e60d95..e8f750d07 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 e703c65c3..1885a60c8 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 3bc569997..263a90b08 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 6144056a8..e46dfda34 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 e0da57fb2..28c4734bd 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 59c123429..559f67e19 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 72755cc35..1e4ec7a32 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 9b40afa2e..260d3c942 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 6c3d12026..50081bc5a 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 4f7497625..9df3aa27a 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 8fca1916f..f32652da9 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 7e233950c..0b66b2791 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 f3abd33c9..0b5136dca 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 3c7b1214e..0ffe43469 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 097637168..21f1f5c7f 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 458c78081..bf1da4275 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 b8323501c..ace158bb9 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 81f8b3d7c..44910fa62 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 aa8199cd0..32d647762 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 4241fa9e2..9765fc1f9 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 9ca87a4b0..09ee2b2b2 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 aae296695..228f9d580 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 4352a7e95..a31093924 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 69c2e2953..f0f844fff 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 33791dd0d..09d3a2592 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 8dd0f404a..659329e0b 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 cfd56271b..3fbdd8511 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 3464874c8..8f5b162a0 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 e1273a299..2e837478d 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 ecf7ff5ad..317400e1d 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 a90e87cb3..be9f698e1 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 83ab8873b..e5259c6c4 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 ff2cd7c85..590133a78 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 98f6d80be..627f79763 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 a2b0f1363..5921189b7 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 977115ec0..79b5ac153 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 30f4392c5..b7fa57197 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 bccf18caf..f87cf5f74 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 96a73cb5d..ee9e57189 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 6887c00db..ace2d56f2 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 bc2fa2dc3..5efcb2da1 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 93273800e..d83970977 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 2afe4b1ff..fb3228aca 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 8b4218b45..530b46900 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 b3f6cad02..421c4fd4f 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 d4e1dc147..ebc7877f0 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 5a9b13aff..5038294ed 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 b90bc412a..30907bd67 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 7fa0381b6..56032d9d5 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 f1afc6e80..c3a3d660d 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 97cc03919..0083f92d8 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 4aca89ef7..43047758e 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 ce22da600..2e8abe5dc 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 3ad4d94ae..d7964552d 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 5c5af070e..fc4c9efcf 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 1a0f9a799..0b2b6fadf 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 8df8edad4..be6bc2383 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 d77ab04e3..d66545e43 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 ddeaa655b..ea433b786 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 308332700..c3c231ede 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 1fe537aad..d067795ac 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 3f17744fb..4bca2544e 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 f03e1b4eb..c0f524e10 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 58d541a8a..85e97661c 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 4d69e4815..126add640 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 4c4a8b246..4c5e38131 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 17f3daa79..0117f9b49 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 c86ea3e59..1f05d1176 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 f97bae5cd..a87a8eeb6 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 e70d37230..0a4599a3d 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 959e53d45..b8487e321 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 149027691..59d042302 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 2b1de17cb..653bb23b7 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 beafa4af0..91b96f78c 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 9a578cf89..d3467d0b8 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 13a83ee55..25141b8bf 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 7da8d0f6a..39be35cb6 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 0a63ed321..5641e2812 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 4bd8f328f..43d41f755 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 11fcbf6f6..ed160d95c 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 3331b57de..284f9bcbd 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 3df77d2fb..292eab85d 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 fac19a6ff..7a925d134 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 d1387ee8e..e4b764686 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 17c812aec..9b27a277b 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 58afa2413..e37d3f84c 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 bda1c07f2..32f2526cc 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 ea9c4f55a..4f9001115 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 b0ec97d98..80a692429 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 f40a02c93..63dad1ab0 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 6de2c9c61..ae526775f 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 0c2fdba6f..b1cef5e40 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 8997abbe6..ee57f069d 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 6adc6273c..d331abef7 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 afaeb5448..b28b6598c 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 8d35e1754..79302b142 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 b7984d21e..475cc2291 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 6988906a2..0abf62df8 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 6c9b776c4..236a26f1b 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 80ebe0d93..abef4c76a 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 3048558e7..0854dedd1 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 d56275fed..40540bb51 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 568ab91e1..8ea389482 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 40d867fa0..11b862a10 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 36b851ff3..7e89f1c9d 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 c13842daa..fad9d2bba 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 ebd28101d..b2fd91327 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 6ec629c9f..689fc045d 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 07e09a9e8..dd0d8e004 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 cde229e4f..f415cfd95 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 8ebd7025d..f9aa3a650 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 fda74030e..edc35f802 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 2aee19042..6a24c1e9c 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 941cfd237..b55293231 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 c5b035740..ba6688cd5 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 f632f3bc8..e3ab2189c 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 7c31c616c..986781b77 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 f1b128162..60b305402 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 52ea82800..120348a04 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 32/40] 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 000000000..389acc647 --- /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 000000000..47bc04256 --- /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 000000000..f8601cf4f --- /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 000000000..e856a73b9 --- /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 000000000..a5277bebf --- /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 000000000..3a857d484 --- /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 000000000..90591a5ae --- /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 000000000..372143657 --- /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 000000000..f8601cf4f --- /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 000000000..904defe84 --- /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 000000000..a2fd6075a --- /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 000000000..f21d4d4c8 --- /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 000000000..ae601a044 --- /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 000000000..1dc94780d --- /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 000000000..d00491fd7 --- /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 000000000..17bf3b749 --- /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 000000000..d47c93de2 --- /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 000000000..1cd236baf --- /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 000000000..56139e6a5 --- /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 000000000..433648d0b --- /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 000000000..1f98000b0 --- /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 000000000..4158c3ae1 --- /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 000000000..e8ee6aba6 --- /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 000000000..7758b29ca --- /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 000000000..54fc96d46 --- /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 000000000..5ad18a3b1 --- /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 000000000..f7522e6e5 --- /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 000000000..b4fba3576 --- /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 33/40] 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 a9732d05e..791659897 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 88da5d5e6..c6c40cacc 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 34/40] Changelog --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index e79b13e6e..c5211922d 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 35/40] Sort bugfixes in changelog --- Changelog.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index c5211922d..c70922942 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 9428dbc94fe43c0132d1ed6c37cf755fe9855723 Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Mon, 25 Oct 2021 11:58:49 +0100 Subject: [PATCH 36/40] 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 c70922942..ff183e22b 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 b015939e2..d531fd77f 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 f11756b25..0b5f97719 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 bf5039204..f0820d930 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -119,6 +119,7 @@ private: 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 000000000..884fb2b5d --- /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 37/40] 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 d531fd77f..d5392ef84 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 0b5f97719..83a9da55c 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 f0820d930..ba445ffbb 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -121,6 +121,7 @@ private: 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 000000000..b99cff215 --- /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 38/40] 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 d5392ef84..076155366 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 83a9da55c..05fdc489b 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 334e69ba1..b08694820 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -1124,6 +1124,8 @@ public: 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 4ad0a0c4b..585c005f6 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 7ce1a7ad3..9073f6ac1 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 5821d0d56..4d80fb43e 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 42f4584ed..8d750beb6 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 2ee03b09e..f8e0896c3 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 cac87c3dd..aaf6f620a 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 cb39b004b..81b9eab8a 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 b9b798431..d32dd2768 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 12d2d9105..7539a99cb 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 fcc8a432b..81e6e6b15 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 8e1ca503c..7d3dd5640 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 000000000..a459698a7 --- /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 39/40] 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 ffb1d345c..4844eaae3 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 40/40] 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 047480f14..f907f83f5 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)