mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #12047 from ethereum/fixFixedBytesCompilerUtils
Properly handle fixed-byte-like types.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
--storage-layout
|
||||
@@ -0,0 +1,2 @@
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> storage_layout_user_defined/input.sol
|
||||
@@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL v3
|
||||
type MyInt128 is int128;
|
||||
type MyInt8 is int8;
|
||||
contract C {
|
||||
// slot 0
|
||||
MyInt128 a;
|
||||
MyInt128 b;
|
||||
// slot 1
|
||||
MyInt128 c;
|
||||
MyInt8 d;
|
||||
MyInt8 e;
|
||||
MyInt8 f;
|
||||
MyInt8 g;
|
||||
// slot 2
|
||||
MyInt8 h;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
======= storage_layout_user_defined/input.sol:C =======
|
||||
Contract Storage Layout:
|
||||
{"storage":[{"astId":7,"contract":"storage_layout_user_defined/input.sol:C","label":"a","offset":0,"slot":"0","type":"t_userDefinedValueType(MyInt128)2"},{"astId":10,"contract":"storage_layout_user_defined/input.sol:C","label":"b","offset":16,"slot":"0","type":"t_userDefinedValueType(MyInt128)2"},{"astId":13,"contract":"storage_layout_user_defined/input.sol:C","label":"c","offset":0,"slot":"1","type":"t_userDefinedValueType(MyInt128)2"},{"astId":16,"contract":"storage_layout_user_defined/input.sol:C","label":"d","offset":16,"slot":"1","type":"t_userDefinedValueType(MyInt8)4"},{"astId":19,"contract":"storage_layout_user_defined/input.sol:C","label":"e","offset":17,"slot":"1","type":"t_userDefinedValueType(MyInt8)4"},{"astId":22,"contract":"storage_layout_user_defined/input.sol:C","label":"f","offset":18,"slot":"1","type":"t_userDefinedValueType(MyInt8)4"},{"astId":25,"contract":"storage_layout_user_defined/input.sol:C","label":"g","offset":19,"slot":"1","type":"t_userDefinedValueType(MyInt8)4"},{"astId":28,"contract":"storage_layout_user_defined/input.sol:C","label":"h","offset":20,"slot":"1","type":"t_userDefinedValueType(MyInt8)4"}],"types":{"t_userDefinedValueType(MyInt128)2":{"encoding":"inplace","label":"MyInt128","numberOfBytes":"16"},"t_userDefinedValueType(MyInt8)4":{"encoding":"inplace","label":"MyInt8","numberOfBytes":"1"}}}
|
||||
@@ -51,13 +51,13 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test_f() -> true
|
||||
// gas irOptimized: 122656
|
||||
// gas legacy: 125037
|
||||
// gas legacyOptimized: 122605
|
||||
// gas irOptimized: 122887
|
||||
// gas legacy: 126168
|
||||
// gas legacyOptimized: 123199
|
||||
// test_g() -> true
|
||||
// gas irOptimized: 95908
|
||||
// gas legacy: 100586
|
||||
// gas legacyOptimized: 95996
|
||||
// gas irOptimized: 96673
|
||||
// gas legacy: 101311
|
||||
// gas legacyOptimized: 96566
|
||||
// addresses(uint256): 0 -> 0x18
|
||||
// addresses(uint256): 1 -> 0x19
|
||||
// addresses(uint256): 3 -> 0x1b
|
||||
|
||||
@@ -31,7 +31,7 @@ contract C {
|
||||
// write_a() ->
|
||||
// a() -> 0x2001
|
||||
// write_b() ->
|
||||
// b() -> 0xf00e000000000000000000000000000000000000000000000000000000000000
|
||||
// get_b(uint256): 0 -> 0xf000000000000000000000000000000000000000000000000000000000000000
|
||||
// get_b(uint256): 1 -> 0x0e00000000000000000000000000000000000000000000000000000000000000
|
||||
// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000
|
||||
// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000
|
||||
// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000
|
||||
// get_b(uint256): 2 -> FAILURE, hex"4e487b71", 0x32
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
type MyInt8 is int8;
|
||||
contract C {
|
||||
MyInt8 public x = MyInt8.wrap(-5);
|
||||
|
||||
/// The most significant bit is flipped to 0
|
||||
function create_dirty_slot() external {
|
||||
uint mask = 2**255 -1;
|
||||
assembly {
|
||||
let value := sload(x.slot)
|
||||
sstore(x.slot, and(mask, value))
|
||||
}
|
||||
}
|
||||
|
||||
function read_unclean_value() external returns (bytes32 ret) {
|
||||
MyInt8 value = x;
|
||||
assembly {
|
||||
ret := value
|
||||
}
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// x() -> -5
|
||||
// create_dirty_slot() ->
|
||||
// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb
|
||||
@@ -0,0 +1,21 @@
|
||||
type MyInt is int16;
|
||||
type MyBytes is bytes2;
|
||||
contract C {
|
||||
MyInt immutable a = MyInt.wrap(-2);
|
||||
MyBytes immutable b = MyBytes.wrap("ab");
|
||||
function() internal returns (uint) immutable f = g;
|
||||
function direct() view external returns (MyInt, MyBytes) {
|
||||
return (a, b);
|
||||
}
|
||||
function viaasm() view external returns (bytes32 x, bytes32 y) {
|
||||
MyInt _a = a;
|
||||
MyBytes _b = b;
|
||||
assembly { x := _a y := _b }
|
||||
}
|
||||
function g() internal pure returns (uint) { return 2; }
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// direct() -> -2, 0x6162000000000000000000000000000000000000000000000000000000000000
|
||||
// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000
|
||||
@@ -0,0 +1,74 @@
|
||||
type MyInt8 is int8;
|
||||
type MyAddress is address;
|
||||
type MyInt96 is int96;
|
||||
|
||||
contract C {
|
||||
MyInt8 a;
|
||||
MyInt8 b;
|
||||
MyInt8 c;
|
||||
MyAddress d;
|
||||
|
||||
MyAddress e;
|
||||
|
||||
MyAddress f;
|
||||
MyInt96 g;
|
||||
|
||||
function storage_a() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := a.slot
|
||||
offset := a.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_b() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := b.slot
|
||||
offset := b.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_c() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := d.slot
|
||||
offset := c.offset
|
||||
}
|
||||
}
|
||||
function storage_d() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := d.slot
|
||||
offset := d.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_e() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := e.slot
|
||||
offset := e.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_f() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := f.slot
|
||||
offset := f.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_g() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := g.slot
|
||||
offset := g.offset
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage_a() -> 0, 0
|
||||
// storage_b() -> 0, 1
|
||||
// storage_c() -> 0, 2
|
||||
// storage_d() -> 0, 3
|
||||
// storage_e() -> 1, 0
|
||||
// storage_f() -> 2, 0
|
||||
// storage_g() -> 2, 0x14
|
||||
@@ -0,0 +1,167 @@
|
||||
type MyInt64 is int64;
|
||||
struct HalfSlot {
|
||||
MyInt64 a;
|
||||
MyInt64 b;
|
||||
}
|
||||
|
||||
struct RegularHalfSlot {
|
||||
int64 a;
|
||||
int64 b;
|
||||
}
|
||||
|
||||
type MyAddress is address;
|
||||
type MyInt96 is int96;
|
||||
struct FullSlot {
|
||||
MyInt96 a;
|
||||
MyAddress b;
|
||||
}
|
||||
struct RegularFullSlot {
|
||||
int96 a;
|
||||
address b;
|
||||
}
|
||||
|
||||
contract C {
|
||||
HalfSlot public a;
|
||||
RegularHalfSlot public ra;
|
||||
|
||||
HalfSlot public b;
|
||||
RegularHalfSlot public rb;
|
||||
|
||||
HalfSlot public c;
|
||||
RegularHalfSlot public rc;
|
||||
|
||||
FullSlot public d;
|
||||
RegularFullSlot public rd;
|
||||
|
||||
function storage_a() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := a.slot
|
||||
offset := a.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_ra() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := ra.slot
|
||||
offset := ra.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_b() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := b.slot
|
||||
offset := b.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_rb() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := rb.slot
|
||||
offset := rb.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_c() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := c.slot
|
||||
offset := c.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_rc() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := rc.slot
|
||||
offset := rc.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_d() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := d.slot
|
||||
offset := d.offset
|
||||
}
|
||||
}
|
||||
|
||||
function storage_rd() pure external returns(uint slot, uint offset) {
|
||||
assembly {
|
||||
slot := rd.slot
|
||||
offset := rd.offset
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function set_a(MyInt64 _a, MyInt64 _b) external {
|
||||
a.a = _a;
|
||||
a.b = _b;
|
||||
}
|
||||
|
||||
function set_ra(int64 _a, int64 _b) external {
|
||||
ra.a = _a;
|
||||
ra.b = _b;
|
||||
}
|
||||
|
||||
function set_b(MyInt64 _a, MyInt64 _b) external {
|
||||
b.a = _a;
|
||||
b.b = _b;
|
||||
}
|
||||
|
||||
function set_rb(int64 _a, int64 _b) external {
|
||||
rb.a = _a;
|
||||
rb.b = _b;
|
||||
}
|
||||
|
||||
function set_c(MyInt64 _a, MyInt64 _b) external {
|
||||
c.a = _a;
|
||||
c.b = _b;
|
||||
}
|
||||
|
||||
function set_rc(int64 _a, int64 _b) external {
|
||||
rc.a = _a;
|
||||
rc.b = _b;
|
||||
}
|
||||
|
||||
function set_d(MyInt96 _a, MyAddress _b) external {
|
||||
d.a = _a;
|
||||
d.b = _b;
|
||||
}
|
||||
|
||||
function set_rd(int96 _a, address _b) external {
|
||||
rd.a = _a;
|
||||
rd.b = _b;
|
||||
}
|
||||
|
||||
function read_slot(uint slot) view external returns (uint value) {
|
||||
assembly {
|
||||
value := sload(slot)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage_a() -> 0, 0
|
||||
// set_a(int64,int64): 100, 200 ->
|
||||
// read_slot(uint256): 0 -> 0xc80000000000000064
|
||||
// storage_ra() -> 1, 0
|
||||
// set_ra(int64,int64): 100, 200 ->
|
||||
// read_slot(uint256): 1 -> 0xc80000000000000064
|
||||
// storage_b() -> 2, 0
|
||||
// set_b(int64,int64): 0, 200 ->
|
||||
// read_slot(uint256): 2 -> 3689348814741910323200
|
||||
// storage_rb() -> 3, 0
|
||||
// set_rb(int64,int64): 0, 200 ->
|
||||
// read_slot(uint256): 3 -> 3689348814741910323200
|
||||
// storage_c() -> 4, 0
|
||||
// set_c(int64,int64): 100, 0 ->
|
||||
// read_slot(uint256): 4 -> 0x64
|
||||
// storage_rc() -> 5, 0
|
||||
// set_rc(int64,int64): 100, 0 ->
|
||||
// read_slot(uint256): 5 -> 0x64
|
||||
// storage_d() -> 6, 0
|
||||
// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->
|
||||
// read_slot(uint256): 6 -> -39614081257132168796771975169
|
||||
// storage_rd() -> 7, 0
|
||||
// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->
|
||||
// read_slot(uint256): 7 -> -39614081257132168796771975169
|
||||
@@ -0,0 +1,35 @@
|
||||
type MyInt is int16;
|
||||
contract C {
|
||||
bytes2 first = "ab";
|
||||
MyInt public a = MyInt.wrap(-2);
|
||||
bytes2 third = "ef";
|
||||
function direct() external returns (MyInt) {
|
||||
return a;
|
||||
}
|
||||
function indirect() external returns (int16) {
|
||||
return MyInt.unwrap(a);
|
||||
}
|
||||
function toMemDirect() external returns (MyInt[1] memory) {
|
||||
return [a];
|
||||
}
|
||||
function toMemIndirect() external returns (int16[1] memory) {
|
||||
return [MyInt.unwrap(a)];
|
||||
}
|
||||
function div() external returns (int16) {
|
||||
return MyInt.unwrap(a) / 2;
|
||||
}
|
||||
function viaasm() external returns (bytes32 x) {
|
||||
MyInt st = a;
|
||||
assembly { x := st }
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// a() -> -2
|
||||
// direct() -> -2
|
||||
// indirect() -> -2
|
||||
// toMemDirect() -> -2
|
||||
// toMemIndirect() -> -2
|
||||
// div() -> -1
|
||||
// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
|
||||
Reference in New Issue
Block a user