newyork: Terminate object code with the implicit EVM return - #598
Open
dimartiro wants to merge 2 commits into
Open
newyork: Terminate object code with the implicit EVM return#598dimartiro wants to merge 2 commits into
dimartiro wants to merge 2 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
--newyorkcrashes in the linker on a Yul object whose_deployedruntime code block is empty:The default pipeline compiles the same input fine.
Cause
The panic is fallout. The actual problem is a silent miscompile one step earlier.
Code::into_llvmin the legacy pipeline terminates every code block with an implicitstop("The EVM lets the code return implicitly").
LlvmCodegen::generate_objectinnewyorkdoes not,so a block that falls off the end reaches the
__entryis markedNoReturnand putsunreatwo calls. A__runtimethat returns therefore makes theis_deploy ==d LLVM removes thedispatch entirely:
Calling the deployed contract would run the constructor. The linker then sees exports whose
reachability no longer agrees and asserts.
Fix
Append the implicit EVM return in
generate_obcy pipeline does. The runtime function then ends in the exit syscall and keeps itsnoreturn` shape, so the dispatchedge stays live:
Verification
--newyorkbefore--newyorkafter_deployedwith an empty block_deployedwithstop()Across
crates/integration/contracts/*.sol:default pipeline: 83/83 byte-identical, as expected since this only touches
newyork.--newyork: 82/83 byte-identical. The ostruct.sol, and it changes in the right direction.selfdestructlowers to aterminatecall that neither terminates the basic block nor is markednoreturn, so itsfall through and return into__entry'sunreachable`. It now ends peline already ends it:So the diff is
newyorkconverging onto the which is the point of thechange.
Test added:
compiles_newyork_empty_runtime_obpty_runtime_object.yulfixture through
--yul --newyork --bin, mirroring the existingcompiles_newyork_folded_guard_inlined_looprcargo test -p revive-newyork92 passed,cargo test -p resolc --lib69 passed, clippy clean.Note
Found while working on #490, but independent of it: #490 is an object with no
_deployedsub-object at all, which fails in both pipelines with an LLVM verifier error. This one is an object with a_deployedsub-object whoseaffects--newyork. Neither fix depends on the other.