diff --git a/Changelog.md b/Changelog.md index adf89b3ac8f2..5c1420ca346c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,12 +6,14 @@ Language Features: Compiler Features: * Commandline Interface: Disallow selecting the deprecated assembly input mode that was only accessible via `--assemble` instead of treating it as equivalent to `--strict-assembly`. * Commandline Interface: Introduce `--experimental` flag required for enabling the experimental mode. +* Commandline Interface: Replace ``--ethdebug`` and ``--ethdebug-runtime`` with more granular ``--ethdebug-resources``, ``--ethdebug-compilation``, ``--ethdebug-program`` and ``--ethdebug-program-runtime`` flags. Per-contract program outputs no longer force full binary compilation. * EVM: Introduce experimental EVM version `@future`. * General: Introduce the SSA CFG codegen (experimental). * General: Improve performance of sanity checks throughout the compiler implementation. * General: Restrict the existing experimental features (`generic-solidity`, `lsp`, `ethdebug`, `eof`, `evm`, `ast-import`, `evmasm-import`, `ir-ast`, `ssa-cfg`) to experimental mode. * Metadata: Store the state of the experimental mode in JSON and CBOR metadata. In CBOR this broadens the meaning of the existing `experimental` field, which used to indicate only the presence of certain experimental pragmas in the source. * Standard JSON Interface: Introduce `settings.experimental` setting required for enabling the experimental mode. +* Standard JSON Interface: Replace the top-level ``ethdebug`` output with ``ethdebug.resources`` and ``ethdebug.compilation``. Decouple ethdebug outputs from binary compilation so that global ethdebug outputs can be produced without generating bytecode. * Yul Optimizer: Improve performance of control flow side effects collector and function references resolver. Bugfixes: diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 7a97fa54e7b4..478ccd146c0a 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -393,7 +393,7 @@ Input Description // The snippet is quoted and follows the corresponding `@src` annotation. // - `ast-id`: Annotations of the form `@ast-id ` over elements that can be mapped back to a definition in the original Solidity file. // `` is a node ID in the Solidity AST ('ast' output). - // - `ethdebug`: Ethdebug annotations (experimental). + // - `ethdebug`: Ethdebug annotations (experimental). Automatically enabled when any ethdebug output is requested. // - `*`: Wildcard value that can be used to request all non-experimental components. "debugInfo": ["location", "snippet", "ast-id", "ethdebug"] }, @@ -453,8 +453,8 @@ Input Description // transientStorageLayout - Slots, offsets and types of the contract's state variables in transient storage // evm.assembly - New assembly format // evm.legacyAssembly - Old-style assembly format in JSON - // evm.bytecode.ethdebug - Debug information in ethdebug format (ethdebug/format/program schema). Can only be requested when compiling via IR. (experimental) - // evm.deployedBytecode.ethdebug - Like evm.bytecode.ethdebug, but for the runtime part of the contract (experimental) + // evm.bytecode.ethdebug - Debug information in ethdebug format (ethdebug/format/program schema for creation bytecode). Can only be requested when compiling via IR. (experimental) + // evm.deployedBytecode.ethdebug - Debug information in ethdebug format (ethdebug/format/program schema for deployed bytecode). Can only be requested when compiling via IR. (experimental) // evm.bytecode.functionDebugData - Debugging information at function level // evm.bytecode.object - Bytecode object // evm.bytecode.opcodes - Opcodes list @@ -467,6 +467,10 @@ Input Description // evm.gasEstimates - Function gas estimates // yulCFGJson - Control Flow Graph (CFG) of the Single Static Assignment (SSA) form of the contract (experimental) // + // Global level (needs "*" as file name and "*" as contract name): + // ethdebug.resources - Global ethdebug output (ethdebug/format/info/resources schema) containing source list and compiler info (experimental) + // ethdebug.compilation - Global ethdebug compilation output (the 'compilation' key from ethdebug/format/info/resources schema) (experimental) + // // Note that using `evm`, `evm.bytecode`, etc. will select every // target part of that output. Additionally, `*` can be used as a wildcard to request everything. // @@ -696,7 +700,12 @@ Output Description } }, // Global Ethdebug output (experimental) - "ethdebug": {/* ... */ } + "ethdebug": { + // Requested via ethdebug.resources output selection + "resources": {/* ... */}, + // Requested via ethdebug.compilation output selection + "compilation": {/* ... */} + } } @@ -751,26 +760,26 @@ Note that the use of this mode is recorded in the metadata: The table below details all currently available experimental features. -+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+ -| Feature | ID | Affects bytecode | Flag/pragma | -+=======================+==========================+==================+===================================================================+ -| AST import | ``ast-import`` | yes | ``--import-ast`` | -+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+ -| LSP | ``lsp`` | no | ``--lsp`` | -+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+ -| EVM Assembly import | ``evmasm-import`` | yes | ``--import-asm-json`` | -+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+ -| Generic Solidity | ``generic-solidity`` | yes | ``pragma experimental solidity`` | -+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+ -| IR AST | ``ir-ast`` | no | ``--ir-ast-json``, ``--ir-optimized-ast-json`` | -+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+ -| EOF | ``eof`` | yes | ``--experimental-eof-version`` | -+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+ -| Non-mainnet EVMs | ``evm`` | yes | ``--evm-version `` | -+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+ -| Ethdebug | ``ethdebug`` | no | ``--ethdebug``, ``--ethdebug-runtime``, ``--debug-info ethdebug`` | -+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+ -| | | no | ``--yul-cfg-json`` | -| SSA CFG + ``ssa-cfg`` +------------------+-------------------------------------------------------------------+ -| | | yes | ``--via-ssa-cfg`` | -+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+ ++-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +| Feature | ID | Affects bytecode | Flag/pragma | ++=======================+==========================+==================+=========================================================================================================================================+ +| AST import | ``ast-import`` | yes | ``--import-ast`` | ++-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +| LSP | ``lsp`` | no | ``--lsp`` | ++-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +| EVM Assembly import | ``evmasm-import`` | yes | ``--import-asm-json`` | ++-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +| Generic Solidity | ``generic-solidity`` | yes | ``pragma experimental solidity`` | ++-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +| IR AST | ``ir-ast`` | no | ``--ir-ast-json``, ``--ir-optimized-ast-json`` | ++-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +| EOF | ``eof`` | yes | ``--experimental-eof-version`` | ++-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +| Non-mainnet EVMs | ``evm`` | yes | ``--evm-version `` | ++-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +| Ethdebug | ``ethdebug`` | no | ``--ethdebug-resources``, ``--ethdebug-compilation``, ``--ethdebug-program``, ``--ethdebug-program-runtime``, ``--debug-info ethdebug`` | ++-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +| | | no | ``--yul-cfg-json`` | +| SSA CFG + ``ssa-cfg`` +------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +| | | yes | ``--via-ssa-cfg`` | ++-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/libevmasm/AbstractAssemblyStack.h b/libevmasm/AbstractAssemblyStack.h index c4eb804eea41..584c42fdc529 100644 --- a/libevmasm/AbstractAssemblyStack.h +++ b/libevmasm/AbstractAssemblyStack.h @@ -43,6 +43,7 @@ class AbstractAssemblyStack virtual Json ethdebug(std::string const& _contractName) const = 0; virtual Json ethdebugRuntime(std::string const& _contractName) const = 0; virtual Json ethdebug() const = 0; + virtual Json ethdebugCompilation() const = 0; virtual Json assemblyJSON(std::string const& _contractName) const = 0; virtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const = 0; diff --git a/libevmasm/EVMAssemblyStack.cpp b/libevmasm/EVMAssemblyStack.cpp index 34a5c8a2a76c..be9142a8a85c 100644 --- a/libevmasm/EVMAssemblyStack.cpp +++ b/libevmasm/EVMAssemblyStack.cpp @@ -123,6 +123,11 @@ Json EVMAssemblyStack::ethdebug() const return {}; } +Json EVMAssemblyStack::ethdebugCompilation() const +{ + return {}; +} + Json EVMAssemblyStack::assemblyJSON() const { solAssert(m_evmAssembly); diff --git a/libevmasm/EVMAssemblyStack.h b/libevmasm/EVMAssemblyStack.h index 444d444ba9e2..d5efef938a0d 100644 --- a/libevmasm/EVMAssemblyStack.h +++ b/libevmasm/EVMAssemblyStack.h @@ -74,6 +74,7 @@ class EVMAssemblyStack: public AbstractAssemblyStack Json ethdebug(std::string const& _contractName) const override; Json ethdebugRuntime(std::string const& _contractName) const override; Json ethdebug() const override; + Json ethdebugCompilation() const override; Json assemblyJSON() const; Json assemblyJSON(std::string const& _contractName) const override; diff --git a/libevmasm/Ethdebug.cpp b/libevmasm/Ethdebug.cpp index 8b87aadd072a..10ef28f0b694 100644 --- a/libevmasm/Ethdebug.cpp +++ b/libevmasm/Ethdebug.cpp @@ -160,10 +160,16 @@ Json ethdebug::resources(std::vector const& _sources, std::string c sources.push_back(source); } Json result = Json::object(); - result["compilation"] = Json::object(); - result["compilation"]["compiler"] = Json::object(); - result["compilation"]["compiler"]["name"] = "solc"; - result["compilation"]["compiler"]["version"] = _version; + result["compilation"] = compilation(_version); result["compilation"]["sources"] = sources; return result; } + +Json ethdebug::compilation(std::string_view _version) +{ + Json result = Json::object(); + result["compiler"] = Json::object(); + result["compiler"]["name"] = "solc"; + result["compiler"]["version"] = _version; + return result; +} diff --git a/libevmasm/Ethdebug.h b/libevmasm/Ethdebug.h index 2e0df3484ba6..80c9a7e9ba28 100644 --- a/libevmasm/Ethdebug.h +++ b/libevmasm/Ethdebug.h @@ -32,4 +32,7 @@ Json program(std::string_view _name, unsigned _sourceID, Assembly const& _assemb // returns ethdebug/format/info/resources Json resources(std::vector const& _sources, std::string const& _version); +// returns the 'compilation' object from ethdebug/format/info/resources +Json compilation(std::string_view _version); + } // namespace solidity::evmasm::ethdebug diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index bb38555ecc16..03eede8f3611 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -792,6 +792,7 @@ bool CompilerStack::compile(State _stopAfter) // Only compile contracts individually which have been requested. std::map> otherCompilers; + bool requiresFullCompilation = false; for (Source const* source: m_sourceOrder) for (ASTPointer const& node: source->ast->nodes()) @@ -802,6 +803,11 @@ bool CompilerStack::compile(State _stopAfter) try { + // Skip if full compilation is not needed (i.e. no IR/bytecode requested) + if (!pipelineConfig.needsFullCompilation()) + continue; + requiresFullCompilation = true; + if (pipelineConfig.needIR(m_viaIR)) generateIR(*contract, pipelineConfig.needIRCodegenOnly(m_viaIR)); if (pipelineConfig.needBytecode()) @@ -831,7 +837,8 @@ bool CompilerStack::compile(State _stopAfter) solAssert(!m_errorReporter.hasErrors()); m_stackState = CompilationSuccessful; - this->link(); + if (requiresFullCompilation) + this->link(); return true; } @@ -1227,10 +1234,14 @@ Json CompilerStack::interfaceSymbols(std::string const& _contractName) const Json CompilerStack::ethdebug() const { solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful."); - solAssert(!m_contracts.empty()); return evmasm::ethdebug::resources(sourceNames(), VersionString); } +Json CompilerStack::ethdebugCompilation() const +{ + return evmasm::ethdebug::compilation(VersionString); +} + Json CompilerStack::ethdebug(std::string const& _contractName) const { return ethdebug(contract(_contractName), /* runtime */ false); diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 41f61ae4a2b2..383a933d1acf 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -160,6 +160,11 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac return bytecode; } + bool needsFullCompilation() const + { + return irCodegen || irOptimization || bytecode; + } + PipelineConfig operator|(PipelineConfig const& _other) const { return { @@ -410,6 +415,9 @@ class CompilerStack: public langutil::CharStreamProvider, public evmasm::Abstrac /// Prerequisite: Successful call to parse or compile. Json ethdebug() const override; + /// @returns a JSON representing the ethdebug compilation data (compiler name and version). + Json ethdebugCompilation() const override; + /// @returns the Contract Metadata matching the pipeline selected using the viaIR setting. std::string const& metadata(std::string const& _contractName) const { return metadata(contract(_contractName)); } diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index c8dbeb317374..0314abc58c21 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -244,6 +244,18 @@ bool isArtifactRequested(Json const& _outputSelection, std::string const& _file, return false; } +/// @returns boolean indicating whether @_artifacts is contained in @_outputSelection. Helper function. +template +bool areArtifactsRequested(Json const& _outputSelection, Range&& _artifacts) +{ + for (auto const& fileRequests: _outputSelection) + for (auto const& requests: fileRequests) + for (auto const& request: requests) + if (ranges::contains(_artifacts, request.get())) + return true; + return false; +} + /// @returns all artifact names of the EVM object, either for creation or deploy time. std::vector evmObjectComponents(std::string const& _objectKind) { @@ -264,7 +276,7 @@ bool isBinaryRequested(Json const& _outputSelection) static std::vector const outputsThatRequireBinaries = std::vector{ "*", "ir", "irAst", "irOptimized", "irOptimizedAst", "yulCFGJson", - "evm.gasEstimates", "evm.legacyAssembly", "evm.assembly", "ethdebug" + "evm.gasEstimates", "evm.legacyAssembly", "evm.assembly" } + evmObjectComponents("bytecode") + evmObjectComponents("deployedBytecode"); for (auto const& fileRequests: _outputSelection) @@ -294,37 +306,60 @@ bool isEvmBytecodeRequested(Json const& _outputSelection) return false; } -/// @returns true if ethdebug was requested. -bool isEthdebugRequested(Json const& _outputSelection) +/// @returns true if any per-contract ethdebug program output was requested. +bool isEthdebugProgramRequested(Json const& _outputSelection) { if (!_outputSelection.is_object()) return false; - static std::array const ethdebugArtifacts{"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"}; + static std::array constexpr ethdebugArtifacts{"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"}; - for (auto const& fileRequests: _outputSelection) - for (auto const& requests: fileRequests) - for (auto const& request: requests) - if (ranges::contains(ethdebugArtifacts, request.get())) - return true; + return areArtifactsRequested(_outputSelection, ethdebugArtifacts); +} + +/// @returns true if any ethdebug output (global or per-contract) was requested. +bool isAnyEthdebugRequested(Json const& _outputSelection) +{ + if (!_outputSelection.is_object()) + return false; + + static std::array constexpr ethdebugArtifacts{ + "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", + "ethdebug.resources", "ethdebug.compilation" + }; + + return areArtifactsRequested(_outputSelection, ethdebugArtifacts); +} + +/// @returns true if the given global ethdebug output was requested via */*. +bool isEthdebugGlobalOutputRequested(Json const& _outputSelection, std::string const& _artifact) +{ + if (!_outputSelection.is_object()) + return false; + + static std::array constexpr globalEthdebugArtifacts{"ethdebug.resources", "ethdebug.compilation"}; + if (!ranges::contains(globalEthdebugArtifacts, _artifact)) + return false; + + for (auto const& [file, contracts]: _outputSelection.items()) + if (file == "*" && contracts.is_object()) + for (auto const& [contract, requests]: contracts.items()) + if (contract == "*" && requests.is_array()) + for (auto const& request: requests) + if (request.get() == _artifact) + return true; return false; } bool isExperimentalArtifactRequested(Json const& _outputSelection) { - static std::array const experimentalArtifacts{"irAst", "irOptimizedAst", "yulCFGJson"}; + static std::array constexpr experimentalArtifacts{"irAst", "irOptimizedAst", "yulCFGJson"}; - if (isEthdebugRequested(_outputSelection)) + if (isAnyEthdebugRequested(_outputSelection)) return true; - for (auto const& fileRequests: _outputSelection) - for (auto const& requests: fileRequests) - for (auto const& request: requests) - if (ranges::contains(experimentalArtifacts, request.get())) - return true; - - return false; + return areArtifactsRequested(_outputSelection, experimentalArtifacts); } /// @returns The set of selected contracts, along with their compiler pipeline configuration, based @@ -1228,13 +1263,13 @@ std::variant StandardCompiler::parseI ret.modelCheckerSettings.timeout = modelCheckerSettings["timeout"].get(); } - if ((ret.debugInfoSelection.has_value() && ret.debugInfoSelection->ethdebug) || isEthdebugRequested(ret.outputSelection)) + if ((ret.debugInfoSelection.has_value() && ret.debugInfoSelection->ethdebug) || isAnyEthdebugRequested(ret.outputSelection)) { if (ret.language != "Solidity" && ret.language != "Yul") return formatFatalError(Error::Type::FatalError, "'settings.debug.debugInfo' 'ethdebug' is only supported for languages 'Solidity' and 'Yul'."); } - if (isEthdebugRequested(ret.outputSelection)) + if (isEthdebugProgramRequested(ret.outputSelection)) { if (ret.language == "Solidity" && !ret.viaIR) return formatFatalError(Error::Type::FatalError, "'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set."); @@ -1255,11 +1290,9 @@ std::variant StandardCompiler::parseI { if (!ret.experimental) return formatFatalError(Error::Type::FatalError, "Ethdebug annotations are experimental and can only be included in 'settings.debug.debugInfo' by enabling the 'settings.experimental' option."); - if (!pipelineConfig(ret.outputSelection)[""][""].irCodegen && !isEthdebugRequested(ret.outputSelection)) - return formatFatalError(Error::Type::FatalError, "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected."); } - if (isEthdebugRequested(ret.outputSelection)) + if (isEthdebugProgramRequested(ret.outputSelection)) { if (ret.optimiserSettings.runYulOptimiser) solUnimplemented("Optimization is not yet supported with ethdebug."); @@ -1703,8 +1736,13 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu } } - if (isEthdebugRequested(_inputsAndSettings.outputSelection)) - output["ethdebug"] = compilerStack.ethdebug(); + if (analysisSuccess) + { + if (isEthdebugGlobalOutputRequested(_inputsAndSettings.outputSelection, "ethdebug.resources")) + output["ethdebug"]["resources"] = compilerStack.ethdebug(); + if (isEthdebugGlobalOutputRequested(_inputsAndSettings.outputSelection, "ethdebug.compilation")) + output["ethdebug"]["compilation"] = compilerStack.ethdebugCompilation(); + } if (!contractsOutput.empty()) output["contracts"] = contractsOutput; @@ -1867,10 +1905,15 @@ Json StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) output["contracts"][sourceName][contractName]["yulCFGJson"] = stack.cfgJson(); } - if (isEthdebugRequested(_inputsAndSettings.outputSelection)) + if (isEthdebugGlobalOutputRequested(_inputsAndSettings.outputSelection, "ethdebug.resources")) + { + solAssert(_inputsAndSettings.experimental, ""); + output["ethdebug"]["resources"] = evmasm::ethdebug::resources({sourceName}, VersionString); + } + if (isEthdebugGlobalOutputRequested(_inputsAndSettings.outputSelection, "ethdebug.compilation")) { solAssert(_inputsAndSettings.experimental, ""); - output["ethdebug"] = evmasm::ethdebug::resources({sourceName}, VersionString); + output["ethdebug"]["compilation"] = evmasm::ethdebug::compilation(VersionString); } return output; } diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index a805ac3fe598..7403d947dd08 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -151,8 +151,10 @@ static bool needsHumanTargetedStdout(CommandLineOptions const& _options) _options.compiler.outputs.yulCFGJson || _options.compiler.outputs.binary || _options.compiler.outputs.binaryRuntime || - _options.compiler.outputs.ethdebug || - _options.compiler.outputs.ethdebugRuntime || + _options.compiler.outputs.ethdebugResources || + _options.compiler.outputs.ethdebugCompilation || + _options.compiler.outputs.ethdebugProgram || + _options.compiler.outputs.ethdebugProgramRuntime || _options.compiler.outputs.metadata || _options.compiler.outputs.natspecUser || _options.compiler.outputs.natspecDev || @@ -555,24 +557,33 @@ void CommandLineInterface::handleGasEstimation(std::string const& _contract) void CommandLineInterface::handleEthdebug() { - if (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) + if (m_options.compiler.outputs.ethdebugResources) { - std::string ethdebug{jsonPrint(removeNullMembers(m_compiler->ethdebug()), m_options.formatting.json)}; + std::string const ethdebug{jsonPrint(removeNullMembers(m_compiler->ethdebug()), m_options.formatting.json)}; if (!m_options.output.dir.empty()) - createFile("ethdebug.json", ethdebug); + createFile("ethdebug_resources.json", ethdebug); else sout() << "======= Debug Data (ethdebug/format/info/resources) =======" << std::endl << ethdebug << std::endl; } + + if (m_options.compiler.outputs.ethdebugCompilation) + { + std::string const compilation{jsonPrint(removeNullMembers(m_compiler->ethdebugCompilation()), m_options.formatting.json)}; + if (!m_options.output.dir.empty()) + createFile("ethdebug_compilation.json", compilation); + else + sout() << "======= Debug Data (ethdebug compilation) =======" << std::endl << compilation << std::endl; + } } void CommandLineInterface::handleEthdebug(std::string const& _contract) { solAssert(CompilerInputModes.count(m_options.input.mode) == 1); - if (!(m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime)) + if (!(m_options.compiler.outputs.ethdebugProgram || m_options.compiler.outputs.ethdebugProgramRuntime)) return; - if (m_options.compiler.outputs.ethdebug) + if (m_options.compiler.outputs.ethdebugProgram) { std::string ethdebug{jsonPrint(removeNullMembers(m_compiler->ethdebug(_contract)), m_options.formatting.json)}; if (!m_options.output.dir.empty()) @@ -581,7 +592,7 @@ void CommandLineInterface::handleEthdebug(std::string const& _contract) sout() << "Debug Data (ethdebug/format/program):" << std::endl << ethdebug << std::endl; } - if (m_options.compiler.outputs.ethdebugRuntime) + if (m_options.compiler.outputs.ethdebugProgramRuntime) { std::string ethdebugRuntime{jsonPrint(removeNullMembers(m_compiler->ethdebugRuntime(_contract)), m_options.formatting.json)}; if (!m_options.output.dir.empty()) @@ -960,8 +971,8 @@ void CommandLineInterface::compile() m_options.compiler.outputs.opcodes || m_options.compiler.outputs.binary || m_options.compiler.outputs.binaryRuntime || - m_options.compiler.outputs.ethdebug || - m_options.compiler.outputs.ethdebugRuntime || + m_options.compiler.outputs.ethdebugProgram || + m_options.compiler.outputs.ethdebugProgramRuntime || (m_options.compiler.combinedJsonRequests && ( m_options.compiler.combinedJsonRequests->binary || m_options.compiler.combinedJsonRequests->binaryRuntime || @@ -1356,7 +1367,7 @@ void CommandLineInterface::assembleYul(yul::YulStack::Machine _targetMachine) yul::YulStack const& stack = yulStacks[sourceUnitName]; yul::MachineAssemblyObject const& object = objects[sourceUnitName]; - if (m_options.compiler.outputs.ethdebug) + if (m_options.compiler.outputs.ethdebugResources) { sout() << "======= Debug Data (ethdebug/format/info/resources) =======" << std::endl; sout() << util::jsonPrint( @@ -1364,6 +1375,14 @@ void CommandLineInterface::assembleYul(yul::YulStack::Machine _targetMachine) m_options.formatting.json ) << std::endl; } + if (m_options.compiler.outputs.ethdebugCompilation) + { + sout() << "======= Debug Data (ethdebug compilation) =======" << std::endl; + sout() << util::jsonPrint( + evmasm::ethdebug::compilation(VersionString), + m_options.formatting.json + ) << std::endl; + } std::string machine = "EVM"; sout() << std::endl << "======= " << sourceUnitName << " (" << machine << ") =======" << std::endl; @@ -1414,7 +1433,7 @@ void CommandLineInterface::assembleYul(yul::YulStack::Machine _targetMachine) m_options.formatting.json ) << std::endl; } - if (m_options.compiler.outputs.ethdebug) + if (m_options.compiler.outputs.ethdebugProgram) { sout() << std::endl << "Debug Data (ethdebug/format/program):" << std::endl; sout() << util::jsonPrint( diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 08260a6fb803..e48849ea76fb 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -168,8 +168,10 @@ std::vector const& CommandLineParser::experimentalOptionNames() "ir-ast-json", "ir-optimized-ast-json", "yul-cfg-json", - "ethdebug", - "ethdebug-runtime", + "ethdebug-resources", + "ethdebug-compilation", + "ethdebug-program", + "ethdebug-program-runtime", g_strEOFVersion, g_strViaSSACFG, }; @@ -475,7 +477,9 @@ void CommandLineParser::parseOutputSelection() CompilerOutputs::componentName(&CompilerOutputs::astCompactJson), CompilerOutputs::componentName(&CompilerOutputs::asmJson), CompilerOutputs::componentName(&CompilerOutputs::yulCFGJson), - CompilerOutputs::componentName(&CompilerOutputs::ethdebug), + CompilerOutputs::componentName(&CompilerOutputs::ethdebugResources), + CompilerOutputs::componentName(&CompilerOutputs::ethdebugCompilation), + CompilerOutputs::componentName(&CompilerOutputs::ethdebugProgram), }; static std::set const evmAssemblyJsonImportModeOutputs = { CompilerOutputs::componentName(&CompilerOutputs::asm_), @@ -781,13 +785,20 @@ General Information)").c_str(), "(experimental) Control Flow Graph (CFG) of Yul code in Static Single Assignment (SSA) form in JSON format." ) ( - CompilerOutputs::componentName(&CompilerOutputs::ethdebug).c_str(), - "(experimental) Debug information in ethdebug format for all contracts (ethdebug/format/program schema). " - "When enabled, an extra global output containing the ethdebug/format/info/resources schema with information shared by all contracts is automatically enabled as well." + CompilerOutputs::componentName(&CompilerOutputs::ethdebugResources).c_str(), + "(experimental) Global ethdebug output (ethdebug/format/info/resources schema) containing source list and compiler info." ) ( - CompilerOutputs::componentName(&CompilerOutputs::ethdebugRuntime).c_str(), - ("(experimental) Like --" + CompilerOutputs::componentName(&CompilerOutputs::ethdebug) + ", but for the runtime part of the contracts.").c_str() + CompilerOutputs::componentName(&CompilerOutputs::ethdebugCompilation).c_str(), + "(experimental) Global ethdebug compilation output (the 'compilation' key from ethdebug/format/info/resources schema)." + ) + ( + CompilerOutputs::componentName(&CompilerOutputs::ethdebugProgram).c_str(), + "(experimental) Debug information in ethdebug format for all contracts (ethdebug/format/program schema for creation bytecode)." + ) + ( + CompilerOutputs::componentName(&CompilerOutputs::ethdebugProgramRuntime).c_str(), + "(experimental) Debug information in ethdebug format for the runtime part of all contracts (ethdebug/format/program schema for deployed bytecode)." ); desc.add(outputComponents); @@ -1377,7 +1388,7 @@ void CommandLineParser::processArgs() m_options.output.viaSSACFG = m_args.contains(g_strViaSSACFG); - if (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) + if (m_options.compiler.outputs.ethdebugProgram || m_options.compiler.outputs.ethdebugProgramRuntime) { if (m_options.output.viaSSACFG) solUnimplemented("ethdebug is not yet supported with --" + g_strViaSSACFG + "."); @@ -1531,32 +1542,20 @@ void CommandLineParser::processArgs() m_options.input.mode == InputMode::EVMAssemblerJSON ); - bool incompatibleEthdebugOutputs = - m_options.compiler.outputs.asmJson || m_options.compiler.outputs.irAstJson || m_options.compiler.outputs.irOptimizedAstJson || - m_options.optimizer.optimizeYul || m_options.optimizer.optimizeEvmasm; - - bool incompatibleEthdebugInputs = m_options.input.mode != InputMode::Compiler; - - static std::string enableEthdebugMessage = - "--" + CompilerOutputs::componentName(&CompilerOutputs::ethdebug) + " / --" + CompilerOutputs::componentName(&CompilerOutputs::ethdebugRuntime); + bool ethdebugProgramRequested = m_options.compiler.outputs.ethdebugProgram || m_options.compiler.outputs.ethdebugProgramRuntime; - static std::string enableIrMessage = "--" + CompilerOutputs::componentName(&CompilerOutputs::ir) + " / --" + CompilerOutputs::componentName(&CompilerOutputs::irOptimized); + std::string const enableEthdebugProgramMessage = fmt::format( + "--{} / --{}", + CompilerOutputs::componentName(&CompilerOutputs::ethdebugProgram), + CompilerOutputs::componentName(&CompilerOutputs::ethdebugProgramRuntime) + ); - if (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) + if (ethdebugProgramRequested) { if (!m_options.output.viaIR) solThrow( CommandLineValidationError, - enableEthdebugMessage + " output can only be selected, if --via-ir was specified." - ); - - if (m_options.output.viaSSACFG) - solUnimplemented("ethdebug is not yet supported with --" + g_strViaSSACFG + "."); - - if (incompatibleEthdebugOutputs) - solThrow( - CommandLineValidationError, - enableEthdebugMessage + " output can only be used with " + enableIrMessage + ". Optimization (using --" + g_strOptimize + ") is not yet supported with ethdebug." + enableEthdebugProgramMessage + " output can only be selected, if --via-ir was specified." ); if (!m_options.output.debugInfoSelection.has_value()) @@ -1569,25 +1568,29 @@ void CommandLineParser::processArgs() if (!m_options.output.debugInfoSelection->ethdebug) solThrow( CommandLineValidationError, - "--debug-info must contain ethdebug, when compiling with " + enableEthdebugMessage + "." + "--debug-info must contain ethdebug, when compiling with " + enableEthdebugProgramMessage + "." ); } } if ( m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug && - (!(m_options.compiler.outputs.ir || m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) || incompatibleEthdebugOutputs) + m_options.input.mode != InputMode::Compiler ) solThrow( CommandLineValidationError, - "--debug-info ethdebug can only be used with " + enableIrMessage + " and/or " + enableEthdebugMessage + ". Optimization (using --" + g_strOptimize + ") is not yet supported with ethdebug." + "Invalid input mode for --debug-info ethdebug." ); - if (m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug && incompatibleEthdebugInputs) - solThrow( - CommandLineValidationError, - "Invalid input mode for --debug-info ethdebug / --ethdebug / --ethdebug-runtime." - ); + if (m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug) + { + if (m_options.output.viaSSACFG) + solUnimplemented("ethdebug is not yet supported with --" + g_strViaSSACFG + "."); + if (m_options.optimizer.optimizeYul || m_options.optimizer.optimizeEvmasm) + solUnimplemented( + "Optimization (using --" + g_strOptimize + ") is not yet supported with ethdebug." + ); + } } void CommandLineParser::parseCombinedJsonOption() diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index 96dbb49c3dce..515864c71df9 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -88,8 +88,10 @@ struct CompilerOutputs {"storage-layout", &CompilerOutputs::storageLayout}, {"transient-storage-layout", &CompilerOutputs::transientStorageLayout}, {"yul-cfg-json", &CompilerOutputs::yulCFGJson}, - {"ethdebug", &CompilerOutputs::ethdebug}, - {"ethdebug-runtime", &CompilerOutputs::ethdebugRuntime}, + {"ethdebug-resources", &CompilerOutputs::ethdebugResources}, + {"ethdebug-compilation", &CompilerOutputs::ethdebugCompilation}, + {"ethdebug-program", &CompilerOutputs::ethdebugProgram}, + {"ethdebug-program-runtime", &CompilerOutputs::ethdebugProgramRuntime}, }; return components; } @@ -112,8 +114,10 @@ struct CompilerOutputs bool metadata = false; bool storageLayout = false; bool transientStorageLayout = false; - bool ethdebug = false; - bool ethdebugRuntime = false; + bool ethdebugResources = false; + bool ethdebugCompilation = false; + bool ethdebugProgram = false; + bool ethdebugProgramRuntime = false; }; struct CombinedJsonRequests diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index b3327ea988c8..c01675a5a86e 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -222,7 +222,7 @@ open("$stdout_path", "w").write(json) EOF # Only do this to files that actually contain ethdebug output, because jq will reformat # the whole file and its formatting differs from `solc --pretty-json` - if jq 'has("ethdebug")' "$stdout_path" --exit-status > /dev/null; then + if jq '[.. | objects | has("ethdebug")] | any' "$stdout_path" --exit-status > /dev/null; then local temporary_file temporary_file=$(mktemp -t cmdline-ethdebug-XXXXXX.tmp) if [[ -e strip-ethdebug ]]; then @@ -231,7 +231,9 @@ EOF ' "$stdout_path" > "$temporary_file" else jq --indent 4 ' - if .ethdebug.compilation.compiler.version? != null then + if .ethdebug.resources.compilation.compiler.version? != null then + .ethdebug.resources.compilation.compiler.version = "" + elif .ethdebug.compilation.compiler.version? != null then .ethdebug.compilation.compiler.version = "" else . diff --git a/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/args b/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/args new file mode 100644 index 000000000000..8dd599e3d575 --- /dev/null +++ b/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/args @@ -0,0 +1 @@ +--experimental --debug-info ethdebug --via-ssa-cfg diff --git a/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/err b/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/err new file mode 100644 index 000000000000..170609e36f60 --- /dev/null +++ b/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/err @@ -0,0 +1 @@ +Error: ethdebug is not yet supported with --via-ssa-cfg. diff --git a/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/exit b/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/input.sol b/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/input.sol new file mode 100644 index 000000000000..415509ef9aef --- /dev/null +++ b/test/cmdlineTests/ethdebug_debuginfo_ssa_cfg/input.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/args b/test/cmdlineTests/ethdebug_eof_container_osaka/args index 49c5bc838258..32d3c3fc0abe 100644 --- a/test/cmdlineTests/ethdebug_eof_container_osaka/args +++ b/test/cmdlineTests/ethdebug_eof_container_osaka/args @@ -1 +1 @@ ---experimental --experimental-eof-version 1 --evm-version osaka --ethdebug --via-ir --pretty-json --json-indent 4 +--experimental --experimental-eof-version 1 --evm-version osaka --ethdebug-compilation --ethdebug-program --ethdebug-program-runtime --via-ir --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/ethdebug_eof_container_osaka/output b/test/cmdlineTests/ethdebug_eof_container_osaka/output index e9b57d885711..58f3ff95d968 100644 --- a/test/cmdlineTests/ethdebug_eof_container_osaka/output +++ b/test/cmdlineTests/ethdebug_eof_container_osaka/output @@ -1,16 +1,8 @@ -======= Debug Data (ethdebug/format/info/resources) ======= +======= Debug Data (ethdebug compilation) ======= { - "compilation": { - "compiler": { - "name": "solc", - "version": "" - }, - "sources": [ - { - "id": 0, - "path": "input.sol" - } - ] + "compiler": { + "name": "solc", + "version": "" } } @@ -251,3 +243,1012 @@ Debug Data (ethdebug/format/program): } ] } +Debug Data of the runtime part (ethdebug/format/program): +{ + "contract": { + "definition": { + "source": { + "id": 0 + } + }, + "name": "C" + }, + "environment": "call", + "instructions": [ + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 67, + "operation": { + "arguments": [ + "0x80" + ], + "mnemonic": "PUSH1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 69, + "operation": { + "arguments": [ + "0x40" + ], + "mnemonic": "PUSH1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 71, + "operation": { + "mnemonic": "MSTORE" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 72, + "operation": { + "arguments": [ + "0x04" + ], + "mnemonic": "PUSH1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 74, + "operation": { + "mnemonic": "CALLDATASIZE" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 75, + "operation": { + "mnemonic": "LT" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 76, + "operation": { + "mnemonic": "ISZERO" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 77, + "operation": { + "arguments": [ + "0x0003" + ], + "mnemonic": "RJUMPI" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 80, + "operation": { + "arguments": [ + "0x0008" + ], + "mnemonic": "JUMPF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 83, + "operation": { + "mnemonic": "PUSH0" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 84, + "operation": { + "mnemonic": "CALLDATALOAD" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 85, + "operation": { + "arguments": [ + "0x0001" + ], + "mnemonic": "CALLF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 88, + "operation": { + "arguments": [ + "0x26121ff0" + ], + "mnemonic": "PUSH4" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 93, + "operation": { + "mnemonic": "EQ" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 94, + "operation": { + "arguments": [ + "0x0003" + ], + "mnemonic": "RJUMPI" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 97, + "operation": { + "arguments": [ + "0xffec" + ], + "mnemonic": "RJUMP" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 100, + "operation": { + "arguments": [ + "0x0007" + ], + "mnemonic": "JUMPF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 103, + "operation": { + "arguments": [ + "0xe0" + ], + "mnemonic": "PUSH1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 105, + "operation": { + "mnemonic": "SHR" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 106, + "operation": { + "mnemonic": "RETF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 107, + "operation": { + "arguments": [ + "0x40" + ], + "mnemonic": "PUSH1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 109, + "operation": { + "mnemonic": "MLOAD" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 110, + "operation": { + "mnemonic": "RETF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 111, + "operation": { + "mnemonic": "PUSH0" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 112, + "operation": { + "mnemonic": "DUP1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 113, + "operation": { + "mnemonic": "REVERT" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 114, + "operation": { + "mnemonic": "PUSH0" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 115, + "operation": { + "mnemonic": "DUP1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 116, + "operation": { + "mnemonic": "REVERT" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 117, + "operation": { + "mnemonic": "PUSH0" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 118, + "operation": { + "mnemonic": "SWAP2" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 119, + "operation": { + "mnemonic": "SUB" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 120, + "operation": { + "mnemonic": "SLT" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 121, + "operation": { + "arguments": [ + "0x0001" + ], + "mnemonic": "RJUMPI" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 124, + "operation": { + "mnemonic": "RETF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 125, + "operation": { + "arguments": [ + "0x0004" + ], + "mnemonic": "JUMPF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 128, + "operation": { + "mnemonic": "PUSH0" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 129, + "operation": { + "mnemonic": "ADD" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 130, + "operation": { + "mnemonic": "RETF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 131, + "operation": { + "mnemonic": "CALLVALUE" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 132, + "operation": { + "arguments": [ + "0x0011" + ], + "mnemonic": "RJUMPI" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 135, + "operation": { + "mnemonic": "CALLDATASIZE" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 136, + "operation": { + "arguments": [ + "0x04" + ], + "mnemonic": "PUSH1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 138, + "operation": { + "arguments": [ + "0x0005" + ], + "mnemonic": "CALLF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 141, + "operation": { + "arguments": [ + "0x0002" + ], + "mnemonic": "CALLF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 144, + "operation": { + "mnemonic": "DUP1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 145, + "operation": { + "mnemonic": "DUP1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 146, + "operation": { + "arguments": [ + "0x0006" + ], + "mnemonic": "CALLF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 149, + "operation": { + "mnemonic": "SUB" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 150, + "operation": { + "mnemonic": "SWAP1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 151, + "operation": { + "mnemonic": "RETURN" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 152, + "operation": { + "arguments": [ + "0x0003" + ], + "mnemonic": "JUMPF" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 155, + "operation": { + "mnemonic": "PUSH0" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 156, + "operation": { + "mnemonic": "DUP1" + } + }, + { + "context": { + "code": { + "range": { + "length": 41, + "offset": 60 + }, + "source": { + "id": 0 + } + } + }, + "offset": 157, + "operation": { + "mnemonic": "REVERT" + } + } + ] +} diff --git a/test/cmdlineTests/ethdebug_on_abstract/args b/test/cmdlineTests/ethdebug_on_abstract/args index c345d483a32a..7a58d286f809 100644 --- a/test/cmdlineTests/ethdebug_on_abstract/args +++ b/test/cmdlineTests/ethdebug_on_abstract/args @@ -1 +1 @@ ---experimental --ethdebug --via-ir --pretty-json --json-indent 4 +--experimental --ethdebug-compilation --ethdebug-program --ethdebug-program-runtime --via-ir --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/ethdebug_on_abstract/output b/test/cmdlineTests/ethdebug_on_abstract/output index 744ec0e77642..6731c36d8915 100644 --- a/test/cmdlineTests/ethdebug_on_abstract/output +++ b/test/cmdlineTests/ethdebug_on_abstract/output @@ -1,19 +1,13 @@ -======= Debug Data (ethdebug/format/info/resources) ======= +======= Debug Data (ethdebug compilation) ======= { - "compilation": { - "compiler": { - "name": "solc", - "version": "" - }, - "sources": [ - { - "id": 0, - "path": "input.sol" - } - ] + "compiler": { + "name": "solc", + "version": "" } } ======= input.sol:C ======= Debug Data (ethdebug/format/program): null +Debug Data of the runtime part (ethdebug/format/program): +null diff --git a/test/cmdlineTests/ethdebug_on_interface/args b/test/cmdlineTests/ethdebug_on_interface/args index c345d483a32a..7a58d286f809 100644 --- a/test/cmdlineTests/ethdebug_on_interface/args +++ b/test/cmdlineTests/ethdebug_on_interface/args @@ -1 +1 @@ ---experimental --ethdebug --via-ir --pretty-json --json-indent 4 +--experimental --ethdebug-compilation --ethdebug-program --ethdebug-program-runtime --via-ir --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/ethdebug_on_interface/output b/test/cmdlineTests/ethdebug_on_interface/output index 744ec0e77642..6731c36d8915 100644 --- a/test/cmdlineTests/ethdebug_on_interface/output +++ b/test/cmdlineTests/ethdebug_on_interface/output @@ -1,19 +1,13 @@ -======= Debug Data (ethdebug/format/info/resources) ======= +======= Debug Data (ethdebug compilation) ======= { - "compilation": { - "compiler": { - "name": "solc", - "version": "" - }, - "sources": [ - { - "id": 0, - "path": "input.sol" - } - ] + "compiler": { + "name": "solc", + "version": "" } } ======= input.sol:C ======= Debug Data (ethdebug/format/program): null +Debug Data of the runtime part (ethdebug/format/program): +null diff --git a/test/cmdlineTests/ethdebug_resources/args b/test/cmdlineTests/ethdebug_resources/args new file mode 100644 index 000000000000..2fe9dcb0aa0c --- /dev/null +++ b/test/cmdlineTests/ethdebug_resources/args @@ -0,0 +1 @@ +--experimental --ethdebug-resources --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/ethdebug_resources/input.sol b/test/cmdlineTests/ethdebug_resources/input.sol new file mode 100644 index 000000000000..415509ef9aef --- /dev/null +++ b/test/cmdlineTests/ethdebug_resources/input.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 +pragma solidity >=0.0; + +contract C { + function f() public {} +} diff --git a/test/cmdlineTests/ethdebug_resources/output b/test/cmdlineTests/ethdebug_resources/output new file mode 100644 index 000000000000..89adfc67cfcf --- /dev/null +++ b/test/cmdlineTests/ethdebug_resources/output @@ -0,0 +1,17 @@ +======= Debug Data (ethdebug/format/info/resources) ======= +{ + "compilation": { + "compiler": { + "name": "solc", + "version": "" + }, + "sources": [ + { + "id": 0, + "path": "input.sol" + } + ] + } +} + +======= input.sol:C ======= diff --git a/test/cmdlineTests/metadata_experimental/args b/test/cmdlineTests/metadata_experimental/args index 4a834e560df6..fa925f16ed8f 100644 --- a/test/cmdlineTests/metadata_experimental/args +++ b/test/cmdlineTests/metadata_experimental/args @@ -1 +1 @@ ---metadata --experimental --via-ir --ethdebug --no-cbor-metadata --pretty-json --json-indent 4 +--metadata --experimental --via-ir --ethdebug-program --ethdebug-compilation --no-cbor-metadata --pretty-json --json-indent 4 diff --git a/test/cmdlineTests/metadata_experimental/output b/test/cmdlineTests/metadata_experimental/output index dc9145d5e812..19ed8dab0387 100644 --- a/test/cmdlineTests/metadata_experimental/output +++ b/test/cmdlineTests/metadata_experimental/output @@ -1,16 +1,8 @@ -======= Debug Data (ethdebug/format/info/resources) ======= +======= Debug Data (ethdebug compilation) ======= { - "compilation": { - "compiler": { - "name": "solc", - "version": "" - }, - "sources": [ - { - "id": 0, - "path": "input.sol" - } - ] + "compiler": { + "name": "solc", + "version": "" } } diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json index 72f16c0ea32f..878b2b41f77a 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json @@ -22,7 +22,8 @@ "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir", - "irOptimized" + "irOptimized", + "ethdebug.resources" ] } } diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/input.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/input.json index 8d85b0ffa1ff..e1104f5b300c 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/input.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/input.json @@ -20,7 +20,8 @@ "*": { "*": [ "evm.bytecode.ethdebug", - "evm.deployedBytecode.ethdebug" + "evm.deployedBytecode.ethdebug", + "ethdebug.resources" ] } } diff --git a/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/output.json b/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/output.json index 57b26680146a..16b6fc2b1015 100644 --- a/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/output.json +++ b/test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/output.json @@ -26,21 +26,23 @@ } }, "ethdebug": { - "compilation": { - "compiler": { - "name": "solc", - "version": "" - }, - "sources": [ - { - "id": 0, - "path": "a.sol" + "resources": { + "compilation": { + "compiler": { + "name": "solc", + "version": "" }, - { - "id": 1, - "path": "b.sol" - } - ] + "sources": [ + { + "id": 0, + "path": "a.sol" + }, + { + "id": 1, + "path": "b.sol" + } + ] + } } }, "sources": { diff --git a/test/cmdlineTests/standard_output_ethdebug_parse_only_incompatible/input.json b/test/cmdlineTests/standard_output_ethdebug_parse_only_incompatible/input.json new file mode 100644 index 000000000000..17afe568db11 --- /dev/null +++ b/test/cmdlineTests/standard_output_ethdebug_parse_only_incompatible/input.json @@ -0,0 +1,22 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C { function f() public pure {} }" + } + }, + "settings": { + "experimental": true, + "stopAfter": "parsing", + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.ethdebug", + "evm.deployedBytecode.ethdebug", + "ethdebug.resources", + "ethdebug.compilation" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_ethdebug_parse_only_incompatible/output.json b/test/cmdlineTests/standard_output_ethdebug_parse_only_incompatible/output.json new file mode 100644 index 000000000000..1699ed88086c --- /dev/null +++ b/test/cmdlineTests/standard_output_ethdebug_parse_only_incompatible/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "Requested output selection conflicts with \"settings.stopAfter\".", + "message": "Requested output selection conflicts with \"settings.stopAfter\".", + "severity": "error", + "type": "JSONError" + } + ] +} diff --git a/test/cmdlineTests/standard_output_ethdebug_selection_compilation/input.json b/test/cmdlineTests/standard_output_ethdebug_selection_compilation/input.json new file mode 100644 index 000000000000..b0379b6b687a --- /dev/null +++ b/test/cmdlineTests/standard_output_ethdebug_selection_compilation/input.json @@ -0,0 +1,18 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C { function f() public pure {} }" + } + }, + "settings": { + "experimental": true, + "outputSelection": { + "*": { + "*": [ + "ethdebug.compilation" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_ethdebug_selection_compilation/output.json b/test/cmdlineTests/standard_output_ethdebug_selection_compilation/output.json new file mode 100644 index 000000000000..cd37d5fdb165 --- /dev/null +++ b/test/cmdlineTests/standard_output_ethdebug_selection_compilation/output.json @@ -0,0 +1,15 @@ +{ + "ethdebug": { + "compilation": { + "compiler": { + "name": "solc", + "version": "" + } + } + }, + "sources": { + "a.sol": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_output_ethdebug_selection_resources/input.json b/test/cmdlineTests/standard_output_ethdebug_selection_resources/input.json new file mode 100644 index 000000000000..7731cef3076e --- /dev/null +++ b/test/cmdlineTests/standard_output_ethdebug_selection_resources/input.json @@ -0,0 +1,18 @@ +{ + "language": "Solidity", + "sources": { + "a.sol": { + "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C { function f() public pure {} }" + } + }, + "settings": { + "experimental": true, + "outputSelection": { + "*": { + "*": [ + "ethdebug.resources" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_output_ethdebug_selection_resources/output.json b/test/cmdlineTests/standard_output_ethdebug_selection_resources/output.json new file mode 100644 index 000000000000..0cbba50a8ab2 --- /dev/null +++ b/test/cmdlineTests/standard_output_ethdebug_selection_resources/output.json @@ -0,0 +1,23 @@ +{ + "ethdebug": { + "resources": { + "compilation": { + "compiler": { + "name": "solc", + "version": "" + }, + "sources": [ + { + "id": 0, + "path": "a.sol" + } + ] + } + } + }, + "sources": { + "a.sol": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json index 2fd0aecf8fc3..b83cf6508863 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json @@ -19,7 +19,8 @@ "*": [ "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", - "ir" + "ir", + "ethdebug.resources" ] } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json index 58fb7b42fb87..ff8dd714040e 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json @@ -19,7 +19,8 @@ "*": [ "evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", - "irOptimized" + "irOptimized", + "ethdebug.resources" ] } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json index 292c86e37542..9bab955c8985 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json @@ -18,7 +18,8 @@ "*": { "*": [ "evm.bytecode.ethdebug", - "ir" + "ir", + "ethdebug.resources" ] } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json index 2e4bb8ec920d..1a3fb90988e2 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json @@ -18,7 +18,8 @@ "*": { "*": [ "evm.bytecode.ethdebug", - "irOptimized" + "irOptimized", + "ethdebug.resources" ] } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json index cd6a3d15bb77..23698d7c12a5 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json @@ -18,7 +18,8 @@ "*": { "*": [ "evm.deployedBytecode.ethdebug", - "ir" + "ir", + "ethdebug.resources" ] } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json index d9a5104f46ac..ce2ae6f33e60 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json @@ -18,7 +18,8 @@ "*": { "*": [ "evm.deployedBytecode.ethdebug", - "irOptimized" + "irOptimized", + "ethdebug.resources" ] } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json index f601332693cd..1034d8d37f05 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json @@ -15,7 +15,8 @@ "*": { "*": [ "evm.bytecode.ethdebug", - "ir" + "ir", + "ethdebug.resources" ] } } diff --git a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json index fb1e11bbcb0c..ba4046a64848 100644 --- a/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json +++ b/test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json @@ -15,7 +15,8 @@ "*": { "*": [ "evm.bytecode.ethdebug", - "irOptimized" + "irOptimized", + "ethdebug.resources" ] } } diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json index 755d770fe63b..c459aadef6f2 100644 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json @@ -11,7 +11,7 @@ "experimental": true, "debug": {"debugInfo": ["ethdebug"]}, "outputSelection": { - "*": {"*": ["ir", "irOptimized", "evm.bytecode.ethdebug"]} + "*": {"*": ["ir", "irOptimized", "evm.bytecode.ethdebug", "ethdebug.resources"]} } } } diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/input.json index b83ec361c14e..7cf3af382d4d 100644 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/input.json +++ b/test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/input.json @@ -13,7 +13,7 @@ "evmVersion": "osaka", "debug": {"debugInfo": ["ethdebug"]}, "outputSelection": { - "*": {"*": ["ir", "irOptimized", "evm.bytecode.ethdebug"]} + "*": {"*": ["ir", "irOptimized", "evm.bytecode.ethdebug", "ethdebug.resources"]} } } } diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json deleted file mode 100644 index e4c9d17e5a87..000000000000 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "language": "Yul", - "sources": { - "C": { - "urls": [ - "in.yul" - ] - } - }, - "settings": { - "experimental": true, - "debug": {"debugInfo": ["ethdebug"]}, - "outputSelection": { - "*": {"*": ["evm.assembly"]} - } - } -} diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/output.json b/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/output.json deleted file mode 100644 index 963bcd8d7d68..000000000000 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/output.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "errors": [ - { - "component": "general", - "formattedMessage": "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", - "message": "'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.", - "severity": "error", - "type": "FatalError" - } - ] -} diff --git a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json index 89127b977c35..c0ae2d50fedb 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json @@ -6,7 +6,7 @@ "settings": { "experimental": true, "outputSelection": { - "*": {"*": ["evm.bytecode.ethdebug"]} + "*": {"*": ["evm.bytecode.ethdebug", "ethdebug.resources"]} } } } diff --git a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/output.json b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/output.json index 3af82e21d392..f78f6ce7c055 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/output.json +++ b/test/cmdlineTests/standard_yul_ethdebug_assign_immutable/output.json @@ -111,17 +111,19 @@ } }, "ethdebug": { - "compilation": { - "compiler": { - "name": "solc", - "version": "" - }, - "sources": [ - { - "id": 0, - "path": "C" - } - ] + "resources": { + "compilation": { + "compiler": { + "name": "solc", + "version": "" + }, + "sources": [ + { + "id": 0, + "path": "C" + } + ] + } } } } diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json index 9d5829df07ea..617c93f688a7 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json @@ -6,7 +6,7 @@ "settings": { "experimental": true, "outputSelection": { - "*": {"*": ["evm.bytecode.ethdebug", "ir"]} + "*": {"*": ["evm.bytecode.ethdebug", "ir", "ethdebug.resources"]} } } } diff --git a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json index da8378a8b6ae..5abd87a0db38 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json @@ -6,7 +6,7 @@ "settings": { "experimental": true, "outputSelection": { - "*": {"*": ["evm.bytecode.ethdebug", "irOptimized"]} + "*": {"*": ["evm.bytecode.ethdebug", "irOptimized", "ethdebug.resources"]} } } } diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/args b/test/cmdlineTests/standard_yul_ethdebug_compilation/args similarity index 100% rename from test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/args rename to test/cmdlineTests/standard_yul_ethdebug_compilation/args diff --git a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/in.yul b/test/cmdlineTests/standard_yul_ethdebug_compilation/in.yul similarity index 99% rename from test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/in.yul rename to test/cmdlineTests/standard_yul_ethdebug_compilation/in.yul index aa564d00ce86..920aef8e9dc2 100644 --- a/test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/in.yul +++ b/test/cmdlineTests/standard_yul_ethdebug_compilation/in.yul @@ -14,3 +14,4 @@ object "C_6_deployed" { /// @src 0:60:101 "contract C {..." } } + diff --git a/test/cmdlineTests/standard_yul_ethdebug_compilation/input.json b/test/cmdlineTests/standard_yul_ethdebug_compilation/input.json new file mode 100644 index 000000000000..66aff6b00a6f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_compilation/input.json @@ -0,0 +1,12 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["in.yul"]} + }, + "settings": { + "experimental": true, + "outputSelection": { + "*": {"*": ["ethdebug.compilation"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_compilation/output.json b/test/cmdlineTests/standard_yul_ethdebug_compilation/output.json new file mode 100644 index 000000000000..d5037bd7d941 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_compilation/output.json @@ -0,0 +1,10 @@ +{ + "ethdebug": { + "compilation": { + "compiler": { + "name": "solc", + "version": "" + } + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json index fcfcaf3bd9ee..ff39d837e10f 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json @@ -6,7 +6,7 @@ "settings": { "experimental": true, "outputSelection": { - "*": {"*": ["evm.deployedBytecode.ethdebug"]} + "*": {"*": ["evm.deployedBytecode.ethdebug", "ethdebug.resources"]} } } } diff --git a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json index 2bedd407b3e5..713c5c84231a 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json @@ -6,7 +6,7 @@ "settings": { "experimental": true, "outputSelection": { - "*": {"*": ["evm.deployedBytecode.ethdebug", "evm.bytecode.ethdebug"]} + "*": {"*": ["evm.deployedBytecode.ethdebug", "evm.bytecode.ethdebug", "ethdebug.resources"]} } } } diff --git a/test/cmdlineTests/standard_yul_ethdebug_eof/input.json b/test/cmdlineTests/standard_yul_ethdebug_eof/input.json index 3455e61d7c9e..ebc74d66bb47 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_eof/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_eof/input.json @@ -8,7 +8,7 @@ "eofVersion": 1, "evmVersion": "osaka", "outputSelection": { - "*": {"*": ["evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir", "irOptimized"]} + "*": {"*": ["evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir", "irOptimized", "ethdebug.resources"]} } } } diff --git a/test/cmdlineTests/standard_yul_ethdebug_ir/input.json b/test/cmdlineTests/standard_yul_ethdebug_ir/input.json index 9d5829df07ea..617c93f688a7 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_ir/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_ir/input.json @@ -6,7 +6,7 @@ "settings": { "experimental": true, "outputSelection": { - "*": {"*": ["evm.bytecode.ethdebug", "ir"]} + "*": {"*": ["evm.bytecode.ethdebug", "ir", "ethdebug.resources"]} } } } diff --git a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json index 2d3610908ac3..abcb5e96dfcd 100644 --- a/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json +++ b/test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json @@ -6,7 +6,7 @@ "settings": { "experimental": true, "outputSelection": { - "*": {"*": ["evm.bytecode.ethdebug", "irOptimize"]} + "*": {"*": ["evm.bytecode.ethdebug", "irOptimize", "ethdebug.resources"]} } } } diff --git a/test/cmdlineTests/standard_yul_ethdebug_resources/args b/test/cmdlineTests/standard_yul_ethdebug_resources/args new file mode 100644 index 000000000000..18532c5a6d3f --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_resources/args @@ -0,0 +1 @@ +--allow-paths . diff --git a/test/cmdlineTests/standard_yul_ethdebug_resources/in.yul b/test/cmdlineTests/standard_yul_ethdebug_resources/in.yul new file mode 100644 index 000000000000..920aef8e9dc2 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_resources/in.yul @@ -0,0 +1,17 @@ +/// @use-src 0:"input.sol" +object "C_6_deployed" { + code { + /// @src 0:60:101 "contract C {..." + mstore(64, 128) + + // f() + fun_f_5() + + /// @src 0:77:99 "function f() public {}" + function fun_f_5() { + sstore(0, 42) + } + /// @src 0:60:101 "contract C {..." + } +} + diff --git a/test/cmdlineTests/standard_yul_ethdebug_resources/input.json b/test/cmdlineTests/standard_yul_ethdebug_resources/input.json new file mode 100644 index 000000000000..65355e85223e --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_resources/input.json @@ -0,0 +1,12 @@ +{ + "language": "Yul", + "sources": { + "C": {"urls": ["in.yul"]} + }, + "settings": { + "experimental": true, + "outputSelection": { + "*": {"*": ["ethdebug.resources"]} + } + } +} diff --git a/test/cmdlineTests/standard_yul_ethdebug_resources/output.json b/test/cmdlineTests/standard_yul_ethdebug_resources/output.json new file mode 100644 index 000000000000..4cd8c9c40a32 --- /dev/null +++ b/test/cmdlineTests/standard_yul_ethdebug_resources/output.json @@ -0,0 +1,18 @@ +{ + "ethdebug": { + "resources": { + "compilation": { + "compiler": { + "name": "solc", + "version": "" + }, + "sources": [ + { + "id": 0, + "path": "C" + } + ] + } + } + } +} diff --git a/test/cmdlineTests/via_ssa_cfg_ethdebug/args b/test/cmdlineTests/via_ssa_cfg_ethdebug/args index fa8be093c03d..7c85efbc7f3c 100644 --- a/test/cmdlineTests/via_ssa_cfg_ethdebug/args +++ b/test/cmdlineTests/via_ssa_cfg_ethdebug/args @@ -1 +1 @@ ---experimental --via-ssa-cfg --ethdebug +--experimental --via-ssa-cfg --ethdebug-program --ethdebug-compilation diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 187ff53a6d46..c13704cc061a 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -2099,21 +2099,21 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) generateExperimentalStandardJson(true, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug"})), [](const Json& result) { - return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); + return result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); } }, { generateExperimentalStandardJson(true, Json::array({"ethdebug"}), Json::array({"evm.deployedBytecode.ethdebug"})), [](const Json& result) { - return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); + return result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); } }, { generateExperimentalStandardJson(true, Json::array({"ethdebug"}), Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), [](const Json& result) { - return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && + return result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); } }, @@ -2121,21 +2121,21 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) generateExperimentalStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug"})), [](const Json& result) { - return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); + return result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); } }, { generateExperimentalStandardJson(true, {}, Json::array({"evm.deployedBytecode.ethdebug"})), [](const Json& result) { - return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); + return result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); } }, { generateExperimentalStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug"})), [](const Json& result) { - return result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && + return result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); } }, @@ -2143,14 +2143,14 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) generateExperimentalStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "ir"})), [](const Json& result) { - return result.dump().find("/// ethdebug: enabled") != std::string::npos && result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); + return result.dump().find("/// ethdebug: enabled") != std::string::npos && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); } }, { generateExperimentalStandardJson(true, {}, Json::array({"evm.deployedBytecode.ethdebug", "ir"})), [](const Json& result) { - return result.dump().find("/// ethdebug: enabled") != std::string::npos && result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); + return result.dump().find("/// ethdebug: enabled") != std::string::npos && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug"); } }, { @@ -2165,7 +2165,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) generateExperimentalStandardJson(true, {}, Json::array({"evm.bytecode.ethdebug", "evm.deployedBytecode.ethdebug", "ir"})), [](const Json& result) { - return result.dump().find("/// ethdebug: enabled") != std::string::npos && result.contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && + return result.dump().find("/// ethdebug: enabled") != std::string::npos && result["contracts"]["fileA"]["C"]["evm"]["deployedBytecode"].contains("ethdebug") && result["contracts"]["fileA"]["C"]["evm"]["bytecode"].contains("ethdebug"); } }, @@ -2212,7 +2212,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output) [](const Json& result) { return result["contracts"]["fileA"]["contractA"]["evm"]["deployedBytecode"].contains("ethdebug") && - result["contracts"]["fileB"]["contractB"]["evm"]["bytecode"].contains("ethdebug") && result.contains("ethdebug"); + result["contracts"]["fileB"]["contractB"]["evm"]["bytecode"].contains("ethdebug"); } } }; diff --git a/test/solc/CommandLineInterface.cpp b/test/solc/CommandLineInterface.cpp index 720c3b154576..db78081d1d3e 100644 --- a/test/solc/CommandLineInterface.cpp +++ b/test/solc/CommandLineInterface.cpp @@ -1414,73 +1414,36 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_ambiguous_import) BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_outputs) { TemporaryDirectory tempDir(TEST_CASE_NAME); - createFilesWithParentDirs({tempDir.path() / "input.sol"}); - static std::vector> tests{ - { - {"solc", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--via-ir", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--via-ir", "--ethdebug", "--optimize", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--via-ir", "--ethdebug", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--via-ir", "--ethdebug", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, - }, - { - {"solc", "--via-ir", "--ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--via-ir", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--via-ir", "--ethdebug-runtime", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--via-ir", "--ethdebug-runtime", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--ethdebug-runtime", "--import-asm-json", tempDir.path().string() + "/input.json"}, - }, + createFilesWithParentDirs({tempDir.path() / "input.sol"}, "pragma solidity >=0.0; contract C { function f() public pure {} }"); + // The old incompatibility between ethdebug and --asm-json / --ir-ast-json / --ir-optimized-ast-json + // has been removed. These combinations are now valid as long as other requirements are met. + static std::vector> supportedCLIFlagCombinations{ { - {"solc", "--via-ir", "--ethdebug-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--via-ir", "--ethdebug-program", "--asm-json", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--via-ir", "--ethdebug-program-runtime", "--asm-json", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--via-ir", "--ethdebug-program", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--debug-info", "ethdebug", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--via-ir", "--ethdebug-program", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--debug-info", "ethdebug", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--debug-info", "ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, + {"solc", "--experimental", "--debug-info", "ethdebug", "--ir-ast-json", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--debug-info", "ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, + {"solc", "--experimental", "--debug-info", "ethdebug", "--ir-optimized-ast-json", tempDir.path().string() + "/input.sol"}, }, - { - {"solc", "--debug-info", "ethdebug", "--asm-json", tempDir.path().string() + "/input.json"}, - } }; - for (auto const& test: tests) + for (auto const& test: supportedCLIFlagCombinations) { OptionsReaderAndMessages result = runCLI(test, ""); - BOOST_REQUIRE(!result.success); + BOOST_REQUIRE(result.success); } } @@ -1490,22 +1453,22 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_incompatible_input_modes) createFilesWithParentDirs({tempDir.path() / "input.json"}); static std::vector> tests{ { - {"solc", "--ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, + {"solc", "--ethdebug-program", "--import-asm-json", tempDir.path().string() + "/input.json"}, }, { - {"solc", "--ethdebug", "--via-ir", "--import-asm-json", tempDir.path().string() + "/input.json"}, + {"solc", "--ethdebug-program", "--via-ir", "--import-asm-json", tempDir.path().string() + "/input.json"}, }, { - {"solc", "--ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, + {"solc", "--ethdebug-program-runtime", "--import-asm-json", tempDir.path().string() + "/input.json"}, }, { {"solc", "--debug-info", "ethdebug", "--import-asm-json", tempDir.path().string() + "/input.json"}, }, { - {"solc", "--ethdebug", "--import-ast", tempDir.path().string() + "/input.json"}, + {"solc", "--ethdebug-program", "--import-ast", tempDir.path().string() + "/input.json"}, }, { - {"solc", "--ethdebug", "--via-ir", "--import-ast", tempDir.path().string() + "/input.json"}, + {"solc", "--ethdebug-program", "--via-ir", "--import-ast", tempDir.path().string() + "/input.json"}, }, { {"solc", "--debug-info", "ethdebug", "--ir", "--import-ast", tempDir.path().string() + "/input.json"}, @@ -1524,50 +1487,18 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_debug_info_ethdebug) createFilesWithParentDirs({tempDir.path() / "input.sol"}, "pragma solidity >=0.0; contract C { function f() public pure {} }"); createFilesWithParentDirs({tempDir.path() / "input.yul"}, "{}"); static std::vector> erroneousCLIFlagCombinations{ + // --debug-info ethdebug with --optimize is not supported { - {"solc", "--experimental", "--debug-info", "ethdebug", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--debug-info", "ethdebug", "--ir-optimized", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--debug-info", "ethdebug", "--optimize", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--debug-info", "ethdebug", "--ethdebug", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--ethdebug-runtime", "--strict-assembly", tempDir.path().string() + "/input.yul"}, + {"solc", "--experimental", "--debug-info", "ethdebug", "--optimize", "--ir", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug", "--ethdebug-runtime", "--strict-assembly", tempDir.path().string() + "/input.yul"}, + {"solc", "--experimental", "--debug-info", "location", "--ethdebug-program", "--via-ir", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--debug-info", "ethdebug", "--ethdebug", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--debug-info", "location", "--ethdebug-program-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--debug-info", "ethdebug", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--debug-info", "ethdebug", "--ethdebug", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--debug-info", "location", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--debug-info", "location", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--debug-info", "location", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--debug-info", "all", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--debug-info", "all", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, - }, - { - {"solc", "--experimental", "--debug-info", "all", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--debug-info", "location", "--ethdebug-program", "--ethdebug-program-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, }, }; static std::vector> supportedCLIFlagCombinations{ @@ -1575,36 +1506,19 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_debug_info_ethdebug) {"solc", "--experimental", "--debug-info", "ethdebug", "--ir", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--debug-info", "ethdebug", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--debug-info", "ethdebug", tempDir.path().string() + "/input.sol"}, }, { - { - "solc", - "--experimental", - "--debug-info", - "ethdebug", - "--ethdebug-runtime", - "--via-ir", - tempDir.path().string() + "/input.sol" - }, + {"solc", "--experimental", "--debug-info", "ethdebug", "--ethdebug-program", "--via-ir", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--debug-info", "ethdebug", "--strict-assembly", tempDir.path().string() + "/input.yul"}, + {"solc", "--experimental", "--debug-info", "ethdebug", "--ethdebug-program-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug", "--strict-assembly", tempDir.path().string() + "/input.yul"}, + {"solc", "--experimental", "--debug-info", "ethdebug", "--ethdebug-program", "--ethdebug-program-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, }, { - { - "solc", - "--experimental", - "--debug-info", - "ethdebug", - "--ethdebug", - "--ethdebug-runtime", - "--via-ir", - tempDir.path().string() + "/input.sol" - }, + {"solc", "--experimental", "--debug-info", "ethdebug", "--strict-assembly", tempDir.path().string() + "/input.yul"}, }, }; @@ -1626,56 +1540,57 @@ BOOST_AUTO_TEST_CASE(cli_ethdebug_ethdebug_output) createFilesWithParentDirs({tempDir.path() / "input.sol"}, "pragma solidity >=0.0; contract C { function f() public pure {} }"); static std::vector> erroneousCLIFlagCombinations{ { - {"solc", "--experimental", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-program", "--ethdebug-program-runtime", "--via-ir", "--optimize", tempDir.path().string() + "/input.sol"}, }, { - { - "solc", - "--experimental", - "--ethdebug-runtime", - "--via-ir", - "--ir-optimized", - "--optimize", - tempDir.path().string() + "/input.sol" - }, + {"solc", "--experimental", "--ethdebug-program-runtime", "--via-ir", "--optimize", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug", "--via-ir", "--ir-optimized", "--optimize", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-program", "--via-ir", "--optimize", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-program", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-program", "--ethdebug-program-runtime", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug-runtime", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-program-runtime", tempDir.path().string() + "/input.sol"}, }, }; static std::vector> supportedCLIFlagCombinations{ { - {"solc", "--experimental", "--ethdebug", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-program", "--via-ir", tempDir.path().string() + "/input.sol"}, + }, + { + {"solc", "--experimental", "--ethdebug-program-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + }, + { + {"solc", "--experimental", "--ethdebug-program", "--ethdebug-program-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + }, + { + {"solc", "--experimental", "--ethdebug-program", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-program-runtime", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug", "--ethdebug-runtime", "--via-ir", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-program", "--ethdebug-program-runtime", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-program", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug-runtime", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-program-runtime", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug", "--ethdebug-runtime", "--via-ir", "--ir", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-resources", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-compilation", tempDir.path().string() + "/input.sol"}, }, { - {"solc", "--experimental", "--ethdebug-runtime", "--via-ir", "--ir-optimized", tempDir.path().string() + "/input.sol"}, + {"solc", "--experimental", "--ethdebug-resources", "--ethdebug-compilation", tempDir.path().string() + "/input.sol"}, }, }; diff --git a/test/solc/CommandLineParser.cpp b/test/solc/CommandLineParser.cpp index 36594465292b..f656f2eda2c6 100644 --- a/test/solc/CommandLineParser.cpp +++ b/test/solc/CommandLineParser.cpp @@ -649,39 +649,55 @@ BOOST_AUTO_TEST_CASE(invalid_optimizer_sequence_without_optimize) BOOST_AUTO_TEST_CASE(ethdebug) { - CommandLineOptions commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--debug-info", "ethdebug", "--ethdebug", "--via-ir"}); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, true); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, false); + // --ethdebug-program with explicit debug-info + CommandLineOptions commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--debug-info", "ethdebug", "--ethdebug-program", "--via-ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgram, true); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgramRuntime, false); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); - commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--debug-info", "ethdebug", "--ethdebug-runtime", "--via-ir"}); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, false); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, true); + // --ethdebug-program-runtime with explicit debug-info + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--debug-info", "ethdebug", "--ethdebug-program-runtime", "--via-ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgram, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgramRuntime, true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); - commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--ethdebug", "--via-ir"}); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, true); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, false); - // debug-info "ethdebug" selected implicitly, - // if compiled with --ethdebug or --ethdebug-runtime and no debug-info was selected. + // --ethdebug-program implicitly enables debug-info ethdebug + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--ethdebug-program", "--via-ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgram, true); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgramRuntime, false); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); - commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--ethdebug-runtime", "--via-ir"}); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, false); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, true); + // --ethdebug-program-runtime implicitly enables debug-info ethdebug + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--ethdebug-program-runtime", "--via-ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgram, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgramRuntime, true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); - commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--ethdebug", "--ethdebug-runtime", "--via-ir"}); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, true); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, true); + // both --ethdebug-program and --ethdebug-program-runtime + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--ethdebug-program", "--ethdebug-program-runtime", "--via-ir"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgram, true); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgramRuntime, true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); + // --debug-info ethdebug with --ir only (no program output) commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--debug-info", "ethdebug", "--ir"}); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebug, false); - BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugRuntime, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgram, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgramRuntime, false); BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ir, true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection.has_value(), true); BOOST_CHECK_EQUAL(commandLineOptions.output.debugInfoSelection->ethdebug, true); + // --ethdebug-resources does not require --via-ir + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--ethdebug-resources"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugResources, true); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugCompilation, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgram, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgramRuntime, false); + // --ethdebug-compilation does not require --via-ir + commandLineOptions = parseCommandLine({"solc", "contract.sol", "--experimental", "--ethdebug-compilation"}); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugResources, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugCompilation, true); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgram, false); + BOOST_CHECK_EQUAL(commandLineOptions.compiler.outputs.ethdebugProgramRuntime, false); } BOOST_AUTO_TEST_CASE(experimental_features_without_experimental_flag) @@ -693,8 +709,10 @@ BOOST_AUTO_TEST_CASE(experimental_features_without_experimental_flag) "--ir-ast-json", "--ir-optimized-ast-json", "--yul-cfg-json", - "--ethdebug", - "--ethdebug-runtime", + "--ethdebug-resources", + "--ethdebug-compilation", + "--ethdebug-program", + "--ethdebug-program-runtime", "--via-ssa-cfg" };