diff --git a/Changelog.md b/Changelog.md index 837f912a7..e58e70cdd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,7 +14,7 @@ Compiler Features: * SMTChecker: Support ``keccak256``, ``sha256``, ``ripemd160`` and ``ecrecover`` in the CHC engine. * Control Flow Graph: Print warning for non-empty functions with unnamed return parameters that are not assigned a value in all code paths. * Command Line Interface: New option ``model-checker-engine`` allows to choose a specific SMTChecker engine. Options are ``all`` (default), ``bmc``, ``chc`` and ``none``. - * Standard JSON: New option ``settings.modelCheckerEngine`` allows to choose a specific SMTChecker engine. Options are ``all`` (default), ``bmc``, ``chc`` and ``none``. + * Standard JSON: New option ``modelCheckerSettings.engine`` allows to choose a specific SMTChecker engine. Options are ``all`` (default), ``bmc``, ``chc`` and ``none``. Bugfixes: diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 568d20f2c..3947bcced 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -342,8 +342,11 @@ Input Description "MyContract": [ "abi", "evm.bytecode.opcodes" ] } }, + }, + "modelCheckerSettings": + { // Choose which model checker engine to use: all (default), bmc, chc, none. - "modelCheckerEngine": "chc" + "engine": "chc" } } diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index bb58abf9b..1a1a013fb 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -396,7 +396,7 @@ std::optional checkKeys(Json::Value const& _input, set cons std::optional checkRootKeys(Json::Value const& _input) { - static set keys{"auxiliaryInput", "language", "settings", "sources"}; + static set keys{"auxiliaryInput", "language", "modelCheckerSettings", "settings", "sources"}; return checkKeys(_input, keys, "root"); } @@ -414,10 +414,16 @@ std::optional checkAuxiliaryInputKeys(Json::Value const& _input) std::optional checkSettingsKeys(Json::Value const& _input) { - static set keys{"parserErrorRecovery", "debug", "evmVersion", "libraries", "metadata", "optimizer", "outputSelection", "remappings", "stopAfter", "modelCheckerEngine"}; + static set keys{"parserErrorRecovery", "debug", "evmVersion", "libraries", "metadata", "optimizer", "outputSelection", "remappings", "stopAfter"}; return checkKeys(_input, keys, "settings"); } +std::optional checkModelCheckerSettingsKeys(Json::Value const& _input) +{ + static set keys{"engine"}; + return checkKeys(_input, keys, "modelCheckerSettings"); +} + std::optional checkOptimizerKeys(Json::Value const& _input) { static set keys{"details", "enabled", "runs"}; @@ -867,11 +873,16 @@ std::variant StandardCompiler: "Requested output selection conflicts with \"settings.stopAfter\"." ); - if (settings.isMember("modelCheckerEngine")) + Json::Value const& modelCheckerSettings = _input.get("modelCheckerSettings", Json::Value()); + + if (auto result = checkModelCheckerSettingsKeys(modelCheckerSettings)) + return *result; + + if (modelCheckerSettings.isMember("engine")) { - if (!settings["modelCheckerEngine"].isString()) - return formatFatalError("JSONError", "modelCheckerEngine must be a string."); - std::optional engine = ModelCheckerEngine::fromString(settings["modelCheckerEngine"].asString()); + if (!modelCheckerSettings["engine"].isString()) + return formatFatalError("JSONError", "modelCheckerSettings.engine must be a string."); + std::optional engine = ModelCheckerEngine::fromString(modelCheckerSettings["engine"].asString()); if (!engine) return formatFatalError("JSONError", "Invalid model checker engine requested."); ret.modelCheckerEngine = *engine; diff --git a/test/cmdlineTests/standard_model_checker_engine_all/input.json b/test/cmdlineTests/standard_model_checker_engine_all/input.json index 0fd433d90..6dbf3647f 100644 --- a/test/cmdlineTests/standard_model_checker_engine_all/input.json +++ b/test/cmdlineTests/standard_model_checker_engine_all/input.json @@ -7,8 +7,8 @@ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma experimental SMTChecker;\ncontract C { function f(uint x) public pure { assert(x > 0); } }" } }, - "settings": + "modelCheckerSettings": { - "modelCheckerEngine": "all" + "engine": "all" } } diff --git a/test/cmdlineTests/standard_model_checker_engine_bmc/input.json b/test/cmdlineTests/standard_model_checker_engine_bmc/input.json index f78bfe838..7395c5b12 100644 --- a/test/cmdlineTests/standard_model_checker_engine_bmc/input.json +++ b/test/cmdlineTests/standard_model_checker_engine_bmc/input.json @@ -7,8 +7,8 @@ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma experimental SMTChecker;\ncontract C { function f(uint x) public pure { assert(x > 0); } }" } }, - "settings": + "modelCheckerSettings": { - "modelCheckerEngine": "bmc" + "engine": "bmc" } } diff --git a/test/cmdlineTests/standard_model_checker_engine_chc/input.json b/test/cmdlineTests/standard_model_checker_engine_chc/input.json index fa887c8da..1a46cb917 100644 --- a/test/cmdlineTests/standard_model_checker_engine_chc/input.json +++ b/test/cmdlineTests/standard_model_checker_engine_chc/input.json @@ -7,8 +7,8 @@ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma experimental SMTChecker;\ncontract C { function f(uint x) public pure { assert(x > 0); } }" } }, - "settings": + "modelCheckerSettings": { - "modelCheckerEngine": "chc" + "engine": "chc" } } diff --git a/test/cmdlineTests/standard_model_checker_engine_none/input.json b/test/cmdlineTests/standard_model_checker_engine_none/input.json index 8804dfcbf..a66a757ac 100644 --- a/test/cmdlineTests/standard_model_checker_engine_none/input.json +++ b/test/cmdlineTests/standard_model_checker_engine_none/input.json @@ -7,8 +7,8 @@ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma experimental SMTChecker;\ncontract C { function f(uint x) public pure { assert(x > 0); } }" } }, - "settings": + "modelCheckerSettings": { - "modelCheckerEngine": "none" + "engine": "none" } }