[Legacy codegen] Higher order bits not sign-extended in signed integer array in storage that may be accessed via inline assembly
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 29
Description
In the semantic test below, legacy codegen does not sign-extend the second element of the storage array but via-ir does. This may be accessed via inline assembly. Bug similar to https://github.com/ethereum/solidity/pull/12050
Note that Solidity access is just fine (i.e., sign-extension happens correctly via legacy or IR). Also note that the value returned by the call to `g()` in the test below is via legacy (i.e., the non-sign-extended value).
```
contract C0 {
int192[2] s3;
constructor(int192[2] memory i0) {
s3 = i0;
}
function f() external returns (int192[2] memory o) { o = s3; }
function g() external returns (uint o) { assembly { o := sload(add(s3.slot, 1)) } }
}
// ====
// compileViaYul: also
// ----
// constructor(): 0x0000000000000000000000000000000000000000000000000000000000000000, 0xFFFFFFFFFFFFFFFFF6F6BEA5083DFED985055AB0D43C9DB425C40FEAC74632E5 ->
// gas irOptimized: 136872
// gas legacy: 179142
// gas legacyOptimized: 135428
// f() -> 0, -221565838963264769260736510461167584867121330438731844891
// g() -> 6055535896423415994575052912746498831235234114025302668005
```
Contributor guide
Research direction
Start by reproducing the embedded semantic test and compare legacy codegen with via-ir for the second int192 storage element and the inline-assembly sload in g(). Trace the legacy storage-array load and sign-extension path; done means legacy codegen matches via-ir for f() and returns the sign-extended value through g().
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, solidity
- Domain
- blockchain, compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100