diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a1119d..32499e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Supported `polkadot-sdk` rev: `2509.0.0` ### Changed - Instruct the LLVM backend and linker to `--relax` (may lead to smaller contract code size). +- Standard JSON mode: Don't forward EVM bytecode related output selections to solc. ## v0.5.0 diff --git a/crates/resolc/src/lib.rs b/crates/resolc/src/lib.rs index 8a9f389..023ed3f 100644 --- a/crates/resolc/src/lib.rs +++ b/crates/resolc/src/lib.rs @@ -209,6 +209,7 @@ pub fn standard_json( .debug_information .unwrap_or(false); solc_input.extend_selection(SolcStandardJsonInputSettingsSelection::new_required()); + solc_input.retain_output_selection(); let mut solc_output = solc.standard_json( &mut solc_input, messages, diff --git a/crates/resolc/src/tests/cli/standard_json.rs b/crates/resolc/src/tests/cli/standard_json.rs index 11aa41f..9a2f79c 100644 --- a/crates/resolc/src/tests/cli/standard_json.rs +++ b/crates/resolc/src/tests/cli/standard_json.rs @@ -1,8 +1,10 @@ //! The tests for running resolc with standard JSON option. +use revive_solc_json_interface::SolcStandardJsonOutput; + use crate::tests::cli::utils::{ assert_command_success, assert_equal_exit_codes, execute_resolc_with_stdin_input, - execute_solc_with_stdin_input, STANDARD_JSON_CONTRACTS_PATH, + execute_solc_with_stdin_input, STANDARD_JSON_CONTRACTS_PATH, STANDARD_JSON_NO_EVM_CODEGEN_PATH, }; const JSON_OPTION: &str = "--standard-json"; @@ -21,3 +23,12 @@ fn runs_with_valid_input_file() { let solc_result = execute_solc_with_stdin_input(arguments, STANDARD_JSON_CONTRACTS_PATH); assert_equal_exit_codes(&solc_result, &resolc_result); } + +#[test] +fn no_evm_codegen_requested() { + let result = execute_resolc_with_stdin_input(&[JSON_OPTION], STANDARD_JSON_NO_EVM_CODEGEN_PATH); + assert_command_success(&result, "EVM codegen std json input fixture should build"); + + let output: SolcStandardJsonOutput = serde_json::from_str(&result.stdout).unwrap(); + assert!(!output.errors.iter().any(|msg| msg.severity == "error")) +} diff --git a/crates/resolc/src/tests/cli/utils.rs b/crates/resolc/src/tests/cli/utils.rs index b9e594b..28eb613 100644 --- a/crates/resolc/src/tests/cli/utils.rs +++ b/crates/resolc/src/tests/cli/utils.rs @@ -18,9 +18,15 @@ pub const YUL_CONTRACT_PATH: &str = "src/tests/data/yul/contract.yul"; /// The memeset YUL contract test fixture path. pub const YUL_MEMSET_CONTRACT_PATH: &str = "src/tests/data/yul/memset.yul"; /// The standard JSON contracts test fixture path. -/// pub const STANDARD_JSON_CONTRACTS_PATH: &str = "src/tests/data/standard_json/solidity_contracts.json"; +/// The standard JSON no EVM codegen test fixture path. +/// +/// This contains EVM bytecode selection flags with provided code +/// that doesn't compile without `viaIr`. Because we remove those +/// selection flags, it should compile fine regardless. +pub const STANDARD_JSON_NO_EVM_CODEGEN_PATH: &str = + "src/tests/data/standard_json/no_evm_codegen.json"; /// The simple Solidity contract containing i256 divisions and remains that should be compiled /// correctly diff --git a/crates/resolc/src/tests/data/standard_json/no_evm_codegen.json b/crates/resolc/src/tests/data/standard_json/no_evm_codegen.json new file mode 100644 index 0000000..b09c73c --- /dev/null +++ b/crates/resolc/src/tests/data/standard_json/no_evm_codegen.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "/Users/omarabdulla/parity/revive-dt/resolc-compiler-tests/fixtures/solidity/translated_semantic_tests/array/copying/array_of_struct_memory_to_storage/array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}" + } + }, + "settings": { + "libraries": {}, + "outputSelection": { + "*": { + "": [ + "ast" + ], + "*": [ + "metadata", + "evm.methodIdentifiers", + "irOptimized", + "evm.bytecode", + "evm.deployedBytecode" + ] + } + }, + "viaIR": true, + "optimizer": { + "enabled": false, + "details": { + "peephole": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + } + } +} \ No newline at end of file diff --git a/crates/solc-json-interface/src/standard_json/input/mod.rs b/crates/solc-json-interface/src/standard_json/input/mod.rs index 9c4f069..c9b2105 100644 --- a/crates/solc-json-interface/src/standard_json/input/mod.rs +++ b/crates/solc-json-interface/src/standard_json/input/mod.rs @@ -210,4 +210,9 @@ impl Input { let _ = source.try_resolve(); }); } + + /// Removes unneded output selections. + pub fn retain_output_selection(&mut self) { + self.settings.retain_output_selection(); + } } diff --git a/crates/solc-json-interface/src/standard_json/input/settings/mod.rs b/crates/solc-json-interface/src/standard_json/input/settings/mod.rs index 2f2ca73..54f96d1 100644 --- a/crates/solc-json-interface/src/standard_json/input/settings/mod.rs +++ b/crates/solc-json-interface/src/standard_json/input/settings/mod.rs @@ -112,4 +112,9 @@ impl Settings { pub fn selection_to_prune(&self) -> Selection { self.output_selection.selection_to_prune() } + + /// Removes unneeded selections. + pub fn retain_output_selection(&mut self) { + self.output_selection.retain(); + } } diff --git a/crates/solc-json-interface/src/standard_json/input/settings/selection/file/flag.rs b/crates/solc-json-interface/src/standard_json/input/settings/selection/file/flag.rs index fc33513..99faaf2 100644 --- a/crates/solc-json-interface/src/standard_json/input/settings/selection/file/flag.rs +++ b/crates/solc-json-interface/src/standard_json/input/settings/selection/file/flag.rs @@ -47,3 +47,16 @@ pub enum Flag { #[serde(rename = "ir")] Ir, } + +impl Flag { + /// Whether this selection flag is required for the revive codegen. + /// + /// Specifically, EVM bytecode and related flags should never be requested. + /// It will be replaced by PVM code anyways. + pub fn is_required_for_codegen(&self) -> bool { + !matches!( + self, + Flag::EVMBC | Flag::EVMDBC | Flag::EVMLA | Flag::EVM | Flag::Assembly + ) + } +} diff --git a/crates/solc-json-interface/src/standard_json/input/settings/selection/mod.rs b/crates/solc-json-interface/src/standard_json/input/settings/selection/mod.rs index 69a70d0..7ed0c94 100644 --- a/crates/solc-json-interface/src/standard_json/input/settings/selection/mod.rs +++ b/crates/solc-json-interface/src/standard_json/input/settings/selection/mod.rs @@ -56,6 +56,14 @@ impl PerFileSelection { pub fn is_empty(&self) -> bool { self.files.is_empty() } + + /// Removes unneeded selections. + pub fn retain(&mut self) { + for file in self.files.values_mut() { + file.per_contract.retain(Flag::is_required_for_codegen); + file.per_file.retain(Flag::is_required_for_codegen); + } + } } /// The `solc --standard-json` output selection. @@ -125,4 +133,11 @@ impl Selection { .contains(path, flag) .unwrap_or(self.all.contains(flag)) } + + /// Removes unneeded selections. + pub fn retain(&mut self) { + self.all.per_file.retain(Flag::is_required_for_codegen); + self.all.per_contract.retain(Flag::is_required_for_codegen); + self.files.retain(); + } }