-
Notifications
You must be signed in to change notification settings - Fork 25
Description
Description
An Internal Compiler Error (ICE) occurs when compiling valid Yul code that defines a function named _ (in --yul mode) or _ or $_ (in --standard-json mode). This is valid Yul, but our naming convention causes a collision with built-in functions.
The internal function name for a user-defined function _ becomes __deploy or __runtime (depending on code context), which collides with the internal function names:
| /// The deploy code function name. | |
| pub const FUNCTION_DEPLOY_CODE: &str = "__deploy"; | |
| /// The runtime code function name. | |
| pub const FUNCTION_RUNTIME_CODE: &str = "__runtime"; |
Note
Related (but different) issue: #474
Detected when trying (using --standard-json mode) to compile resolc-compiler-tests/fixtures/yul/semantic/function_definitions.yul which uses $_ as a function name. Similar to the related issue, the path taken in standard JSON mode goes via solc to get the optimized IR. Solc renames $_ to _, which then causes a collision in resolc.
Minimal Reproduction Using --yul and Function Name _
1. Create a Yul file that triggers the ICE
cat > ice-name-conflict-with-internal.yul << 'EOF'
object "Test" {
code {
{
let size := datasize("Test_deployed")
codecopy(0, dataoffset("Test_deployed"), size)
return(0, size)
}
}
object "Test_deployed" {
code {
{
_()
return(0, 32)
}
function _()
{
mstore(0, 0xdeadbeef)
}
}
}
}
EOF2. Compile the file with resolc
RUST_BACKTRACE=1 resolc --yul ice-name-conflict-with-internal.yul --bin3. For comparison, compile the file with solc
solc --strict-assembly ice-name-conflict-with-internal.yul --binExpected Outcome
The compiler should output PVM bytecode. A function named _ is a valid Yul identifier.
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>' (37758766) panicked at crates/llvm-context/src/polkavm/context/mod.rs:459:9:
ICE: function '_' 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::block::Block as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
6: <revive_llvm_context::polkavm::context::function::runtime::runtime_code::RuntimeCode<B> as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
7: <revive_yul::parser::statement::object::Object as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
8: <revive_yul::parser::statement::object::Object as revive_llvm_context::polkavm::WriteLLVM>::into_llvm
9: resolc::project::contract::Contract::compile
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'main' (37758752) panicked at crates/resolc/src/process/native_process.rs:51:14:
Threading error: Any { .. }
--> ice-name-conflict-with-internal.yul:Test
Minimal Reproduction Using --standard-json and Function Name $_
1. Create the standard JSON input file that triggers the ICE
cat > ice-name-conflict-with-internal-2.yul << 'EOF'
object "Test" {
code {
{
let size := datasize("Test_deployed")
codecopy(0, dataoffset("Test_deployed"), size)
return(0, size)
}
}
object "Test_deployed" {
code {
{
$_()
return(0, 32)
}
function $_()
{
mstore(0, 0xdeadbeef)
}
}
}
}
EOFIn the JSON, make sure optimizer.enabled is false to prevent solc from inlining this simple function (which would prevent detecting the bug/ICE):
cat > ice-name-conflict-with-internal-2.json << EOF
{
"language": "Yul",
"sources": {
"ice-name-conflict-with-internal-2.yul": {
"content": $(cat ice-name-conflict-with-internal-2.yul | jq -Rs .)
}
},
"settings": {
"optimizer": {
"enabled": false
},
"outputSelection": {
"*": {
"*": ["evm.bytecode"]
}
}
}
}
EOF2. Compile the file with resolc
RUST_BACKTRACE=1 resolc --standard-json < ice-name-conflict-with-internal-2.json | jqExpected Outcome
The compiler should output PVM bytecode. A function named $_ is a valid Yul identifier.
Actual Outcome
{
"errors": [
{
"component": "general",
"errorCode": null,
"formattedMessage": "Error: \"/path/to/bin/resolc\" subprocess failed with exit code Some(101):\n\n\nthread '<unnamed>' (37978903) panicked at crates/llvm-context/src/polkavm/context/mod.rs:459:9:\nICE: function '_' declared subsequentally\nstack backtrace:\n 0: __rustc::rust_begin_unwind\n 1: core::panicking::panic_fmt\n 2: revive_llvm_context::polkavm::context::Context::add_function\n 3: <revive_yul::parser::statement::function_definition::FunctionDefinition as revive_llvm_context::polkavm::WriteLLVM>::declare\n 4: <revive_yul::parser::statement::block::Block as revive_llvm_context::polkavm::WriteLLVM>::into_llvm\n 5: <revive_llvm_context::polkavm::context::function::runtime::runtime_code::RuntimeCode<B> as revive_llvm_context::polkavm::WriteLLVM>::into_llvm\n 6: <revive_yul::parser::statement::object::Object as revive_llvm_context::polkavm::WriteLLVM>::into_llvm\n 7: <revive_yul::parser::statement::object::Object as revive_llvm_context::polkavm::WriteLLVM>::into_llvm\n 8: resolc::project::contract::Contract::compile\nnote: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.\n\nthread 'main' (37978889) panicked at crates/resolc/src/process/native_process.rs:51:14:\nThreading error: Any { .. }\nstack backtrace:\n 0: __rustc::rust_begin_unwind\n 1: core::panicking::panic_fmt\n 2: core::result::unwrap_failed\n 3: <resolc::process::native_process::NativeProcess as resolc::process::Process>::run\n 4: resolc::main_inner\n 5: resolc::main\nnote: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.\n--> ice-name-conflict-with-internal-2.yul:Test\n\n",
"message": "\"/path/to/bin/resolc\" subprocess failed with exit code Some(101):\n\n\nthread '<unnamed>' (37978903) panicked at crates/llvm-context/src/polkavm/context/mod.rs:459:9:\nICE: function '_' declared subsequentally\nstack backtrace:\n 0: __rustc::rust_begin_unwind\n 1: core::panicking::panic_fmt\n 2: revive_llvm_context::polkavm::context::Context::add_function\n 3: <revive_yul::parser::statement::function_definition::FunctionDefinition as revive_llvm_context::polkavm::WriteLLVM>::declare\n 4: <revive_yul::parser::statement::block::Block as revive_llvm_context::polkavm::WriteLLVM>::into_llvm\n 5: <revive_llvm_context::polkavm::context::function::runtime::runtime_code::RuntimeCode<B> as revive_llvm_context::polkavm::WriteLLVM>::into_llvm\n 6: <revive_yul::parser::statement::object::Object as revive_llvm_context::polkavm::WriteLLVM>::into_llvm\n 7: <revive_yul::parser::statement::object::Object as revive_llvm_context::polkavm::WriteLLVM>::into_llvm\n 8: resolc::project::contract::Contract::compile\nnote: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.\n\nthread 'main' (37978889) panicked at crates/resolc/src/process/native_process.rs:51:14:\nThreading error: Any { .. }\nstack backtrace:\n 0: __rustc::rust_begin_unwind\n 1: core::panicking::panic_fmt\n 2: core::result::unwrap_failed\n 3: <resolc::process::native_process::NativeProcess as resolc::process::Process>::run\n 4: resolc::main_inner\n 5: resolc::main\nnote: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.\n",
"severity": "error",
"sourceLocation": {
"file": "ice-name-conflict-with-internal-2.yul:Test",
"start": -1,
"end": -1
},
"type": "Error"
}
],
"version": "0.8.33",
"long_version": "0.8.33+commit.64118f21.Darwin.appleclang"
}