Description
Description
Compiling a contract that bypasses the runtime assembly through the use of inline assembly in its constructor results in bytecode that does not match the reported assembly output. The runtime assembly appears to be omitted. While the assembly is unused and unreachable, this seems to be a bug since the compiler does not have an explicit mechanism for stripping unused subassemblies. It also still reports the content of that subassembly as the deployed bytecode (--bin-runtime
).
I think that removal of unreferenced subassemblies would actually be desirable as a feature, but should be performed before assembling and the --asm
output should match what actually ends up in the bytecode. The removal we implemented for EOF should be changed to be performed that way. If we reach assembling with unreferenced subassemblies (e.g. through import of hand-crafted assembly), that should just result in an error.
Environment
- Compiler version: 0.8.28
- Compilation pipeline: both legacy and IR
Steps to Reproduce
test.sol
:
contract C {
constructor() {
assembly {
mstore(0, 42)
return(0, 32)
}
}
}
solc test.sol --bin --bin-runtime --asm --debug-info none
======= test.sol:C =======
EVM assembly:
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
revert(0x00, 0x00)
tag_1:
pop
0x2a
0x00
mstore
0x20
0x00
return
stop
sub_0: assembly {
mstore(0x40, 0x80)
revert(0x00, 0x00)
auxdata: 0xa2646970667358221220778aaeb86dfa577546364e5adeb00b7d3594b3699cd7cad1e2e30a24e14fa5ff64736f6c634300081c0033
}
Binary:
6080604052348015600e575f5ffd5b50602a5f5260205ff3fe
Binary of the runtime part:
60806040525f5ffdfea2646970667358221220778aaeb86dfa577546364e5adeb00b7d3594b3699cd7cad1e2e30a24e14fa5ff64736f6c634300081c0033
Note that the creation bytecode is much shorter than the deployed bytecode and cannot possibly include it.