From d8d998c1143ef60b8038a438af481b8ec60c6841 Mon Sep 17 00:00:00 2001 From: xermicus Date: Mon, 16 Feb 2026 11:03:24 +0100 Subject: [PATCH] Fix Yul mode discarding solc validation errors (#478) In `--yul` mode, resolc now properly exits when solc reports validation errors (e.g., invalid hex literals, variable redeclarations), matching `--standard-json behavior.` `runs_without_input_file` was adapted because it was relying on it where the new behavior correctly matches solc --strict-assembly. Closes #477 Co-authored-by: minimax-m2.5 --------- Signed-off-by: xermicus --- CHANGELOG.md | 1 + crates/resolc/src/cli_utils.rs | 2 ++ crates/resolc/src/lib.rs | 3 ++- crates/resolc/src/tests/cli/yul.rs | 27 +++++++++++-------- .../tests/data/yul/invalid_hex_nibbles.yul | 19 +++++++++++++ 5 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 crates/resolc/src/tests/data/yul/invalid_hex_nibbles.yul diff --git a/CHANGELOG.md b/CHANGELOG.md index 0433fba..127129f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This is a development pre-release. ### Fixed - npm package: The `--bin` CLI flag was not producing bytecode because the `outputSelection` was not updated to explicitly requested it. +- Yul mode now properly exits when solc reports validation errors (e.g., invalid hex literals), matching `--standard-json` behavior. [#477](https://github.com/paritytech/revive/issues/477) ### Changed diff --git a/crates/resolc/src/cli_utils.rs b/crates/resolc/src/cli_utils.rs index c37a034..a34ea81 100644 --- a/crates/resolc/src/cli_utils.rs +++ b/crates/resolc/src/cli_utils.rs @@ -22,6 +22,8 @@ pub const YUL_CONTRACT_PATH: &str = "src/tests/data/yul/contract.yul"; pub const YUL_MEMSET_CONTRACT_PATH: &str = "src/tests/data/yul/memset.yul"; /// The return YUL contract test fixture path. pub const YUL_RETURN_CONTRACT_PATH: &str = "src/tests/data/yul/return.yul"; +/// The invalid YUL contract test fixture path (hex literal with odd number of nibbles). +pub const YUL_INVALID_HEX_NIBBLES_PATH: &str = "src/tests/data/yul/invalid_hex_nibbles.yul"; /// The standard JSON contracts test fixture path. pub const STANDARD_JSON_CONTRACTS_PATH: &str = diff --git a/crates/resolc/src/lib.rs b/crates/resolc/src/lib.rs index 029b5aa..3007e15 100644 --- a/crates/resolc/src/lib.rs +++ b/crates/resolc/src/lib.rs @@ -84,7 +84,8 @@ pub fn yul( memory_config: SolcStandardJsonInputSettingsPolkaVMMemory, ) -> anyhow::Result { let libraries = SolcStandardJsonInputSettingsLibraries::try_from(libraries)?; - solc.validate_yul_paths(input_files, libraries.clone(), messages)?; + let solc_output = solc.validate_yul_paths(input_files, libraries.clone(), messages)?; + solc_output.exit_on_error(); let linker_symbols = libraries.as_linker_symbols()?; let project = Project::try_from_yul_paths(input_files, None, libraries, &debug_config)?; diff --git a/crates/resolc/src/tests/cli/yul.rs b/crates/resolc/src/tests/cli/yul.rs index cdfe92a..ffd7463 100644 --- a/crates/resolc/src/tests/cli/yul.rs +++ b/crates/resolc/src/tests/cli/yul.rs @@ -1,8 +1,8 @@ //! The tests for running resolc with yul option. use crate::cli_utils::{ - assert_command_success, assert_equal_exit_codes, execute_resolc, execute_solc, RESOLC_YUL_FLAG, - SOLC_YUL_FLAG, YUL_CONTRACT_PATH, + assert_command_failure, assert_command_success, assert_equal_exit_codes, execute_resolc, + execute_solc, RESOLC_YUL_FLAG, SOLC_YUL_FLAG, YUL_CONTRACT_PATH, YUL_INVALID_HEX_NIBBLES_PATH, }; #[test] @@ -18,15 +18,20 @@ fn runs_with_valid_input_file() { assert_equal_exit_codes(&solc_result, &resolc_result); } -/// While the `solc` Solidity mode requires output selection, -/// the strict-assembly mode does not. -/// -/// `resolc` exhibits consistent behavior for both modes. #[test] -fn runs_without_input_file() { +fn fails_without_input_file() { let resolc_result = execute_resolc(&[RESOLC_YUL_FLAG]); - assert_command_success(&resolc_result, "Omitting an input file"); - assert!(resolc_result - .stderr - .contains("Compiler run successful. No output requested")); + assert_command_failure(&resolc_result, "Omitting an input file"); + + let solc_result = execute_solc(&[SOLC_YUL_FLAG]); + assert_equal_exit_codes(&solc_result, &resolc_result); +} + +#[test] +fn bails_with_invalid_input_file() { + let resolc_result = execute_resolc(&[YUL_INVALID_HEX_NIBBLES_PATH, RESOLC_YUL_FLAG]); + assert_command_failure(&resolc_result, "Providing an invalid input file"); + + let solc_result = execute_solc(&[YUL_INVALID_HEX_NIBBLES_PATH, SOLC_YUL_FLAG]); + assert_equal_exit_codes(&solc_result, &resolc_result); } diff --git a/crates/resolc/src/tests/data/yul/invalid_hex_nibbles.yul b/crates/resolc/src/tests/data/yul/invalid_hex_nibbles.yul new file mode 100644 index 0000000..2573e33 --- /dev/null +++ b/crates/resolc/src/tests/data/yul/invalid_hex_nibbles.yul @@ -0,0 +1,19 @@ +object "Test" { + code { + { + let size := datasize("Test_deployed") + codecopy(0, dataoffset("Test_deployed"), size) + return(0, size) + } + } + object "Test_deployed" { + code { + { + // Invalid: hex literal with odd number of nibbles. + let x := hex"abc" + mstore(0, x) + return(0, 32) + } + } + } +} \ No newline at end of file