Merge pull request #8374 from ethereum/writeAccessToSlot

Allow access to ``_slot`` for local storage pointer variables.
This commit is contained in:
chriseth
2020-02-25 22:11:13 +01:00
committed by GitHub
8 changed files with 78 additions and 7 deletions
@@ -0,0 +1,33 @@
contract C {
struct S {
uint a;
uint b;
}
mapping(uint => S) public mappingAccess;
function data() internal view returns (S storage _data) {
// We need to assign it from somewhere, otherwise we would
// get an "uninitialized access" error.
_data = mappingAccess[20];
bytes32 slot = keccak256(abi.encode(uint(1), uint(0)));
assembly {
_data_slot := slot
}
}
function set(uint x) public {
data().a = x;
}
function get() public view returns (uint) {
return data().a;
}
}
// ----
// get() -> 0
// mappingAccess(uint256): 1 -> 0, 0
// set(uint256): 4
// get() -> 4
// mappingAccess(uint256): 1 -> 4, 0
@@ -9,5 +9,4 @@ contract C {
}
}
// ----
// TypeError: (114-120): Storage variables cannot be assigned to.
// TypeError: (138-146): Storage variables cannot be assigned to.
// TypeError: (138-146): Only _slot can be assigned to.
@@ -0,0 +1,12 @@
contract C {
uint[] x;
fallback() external {
assembly {
x_slot := 1
x_offset := 2
}
}
}
// ----
// TypeError: (84-90): State variables cannot be assigned to - you have to use "sstore()".
// TypeError: (108-116): State variables cannot be assigned to - you have to use "sstore()".
@@ -0,0 +1,12 @@
contract C {
uint[] x;
fallback() external {
uint[] storage y = x;
assembly {
y_slot := 1
y_offset := 2
}
}
}
// ----
// TypeError: (138-146): Only _slot can be assigned to.