You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The compiler crashes with an Internal Compiler Error (ICE) when compiling valid Yul code that defines functions with the same name in separate sibling blocks using --yul mode. This includes e.g. switch case blocks and if blocks. This is valid Yul because functions are scoped to their enclosing block, but the compiler treats them as duplicate declarations.
Note: This bug does not affect --standard-json mode because this code path goes through solc to get the optimized IR, and solc renames the duplicate function names (see section "Why Standard JSON Mode Is Not Affected").
The compiler should output PVM bytecode. The two f functions are in separate case blocks and should not conflict.
Actual Outcome
solc outputs EVM bytecode.
resolc panics with an ICE:
Error: "/path/to/bin/resolc" subprocess failed with exit code Some(101):
thread '<unnamed>' (37651576) panicked at crates/llvm-context/src/polkavm/context/mod.rs:459:9:
ICE: function 'f' declared subsequentally
stack backtrace:
0: __rustc::rust_begin_unwind
1: core::panicking::panic_fmt
2: revive_llvm_context::polkavm::context::Context::add_function
3: <revive_yul::parser::statement::function_definition::FunctionDefinition as revive_llvm_context::polkavm::WriteLLVM>::declare
4: <revive_yul::parser::statement::block::Block as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
5: <revive_yul::parser::statement::switch::Switch as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
6: <revive_yul::parser::statement::block::Block as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
7: <revive_yul::parser::statement::block::Block as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
8: <revive_llvm_context::polkavm::context::function::runtime::runtime_code::RuntimeCode<B> as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
9: <revive_yul::parser::statement::object::Object as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
10: <revive_yul::parser::statement::object::Object as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
11: resolc::project::contract::Contract::compile
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'main' (37651563) panicked at crates/resolc/src/process/native_process.rs:51:14:
Threading error: Any { .. }
stack backtrace:
0: __rustc::rust_begin_unwind
1: core::panicking::panic_fmt
2: core::result::unwrap_failed
3: <resolc::process::native_process::NativeProcess as resolc::process::Process>::run
4: resolc::main_inner
5: resolc::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
--> ice-name-conflict-in-switch.yul:Test
Why Standard JSON Mode Is Not Affected
When using --standard-json mode we first go through solc getting the optimized IR. Depending on whether optimizer.enabled is true or false, solc resolves the duplicate function names differently:
With optimizer enabled (simple functions are inlined):
// Original
case 0 {
function f() -> ret { ret := 1 }
mstore(0, f())
}
case 1 {
function f() -> ret { ret := 2 }
mstore(0, f())
}
// `irOptimized`
case 0 {
mstore(0, 1)
return(0, 32)
}
case 1 {
mstore(0, 2)
return(0, 32)
}
With optimizer disabled (functions are hoisted to the code block level and duplicate names are renamed):
// `irOptimized`
{
switch calldataload(0)
case 0 {
mstore(0, f())
return(0, 32)
}
case 1 {
mstore(0, f_1()) // Renamed!
return(0, 32)
}
}
function f() -> ret { ret := 1 }
function f_1() -> ret { ret := 2 } // Renamed!
1. Create the standard JSON input file
Using the ice-name-conflict-in-switch.yul file created in the earlier section:
Description
The compiler crashes with an Internal Compiler Error (ICE) when compiling valid Yul code that defines functions with the same name in separate sibling blocks using
--yulmode. This includes e.g.switchcase blocks andifblocks. This is valid Yul because functions are scoped to their enclosing block, but the compiler treats them as duplicate declarations.Note: This bug does not affect
--standard-jsonmode because this code path goes through solc to get the optimized IR, and solc renames the duplicate function names (see section "Why Standard JSON Mode Is Not Affected").Detected when trying to compile: resolc-compiler-tests/fixtures/yul/semantic/function_definitions.yul
Note
Related (but different) issue: #475
Minimal Reproduction
1. Create a Yul file that triggers the ICE
2. Compile the file with resolc
3. For comparison, compile the file with solc
Expected Outcome
The compiler should output PVM bytecode. The two
ffunctions are in separatecaseblocks and should not conflict.Actual Outcome
solc outputs EVM bytecode.
resolc panics with an ICE:
Why Standard JSON Mode Is Not Affected
When using
--standard-jsonmode we first go through solc getting the optimized IR. Depending on whetheroptimizer.enabledistrueorfalse, solc resolves the duplicate function names differently:With optimizer enabled (simple functions are inlined):
With optimizer disabled (functions are hoisted to the code block level and duplicate names are renamed):
1. Create the standard JSON input file
Using the
ice-name-conflict-in-switch.yulfile created in the earlier section:2. Compile the file with resolc
resolc --standard-json < ice-name-conflict-in-switch.json