mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
UserDefinedValueType.storageBytes() is correctly set
Previously it returned 32 bytes for all types, which was wasteful. This commit changes it to return the storage bytes of the underlying type.
This commit is contained in:
parent
7e7c68e5bf
commit
6109b5c3a1
@ -2,6 +2,7 @@
|
||||
|
||||
Important Bugfixes:
|
||||
* Immutables: Properly perform sign extension on signed immutables.
|
||||
* User Defined Value Type: Fix storage layout of user defined value types for underlying types shorter than 32 bytes.
|
||||
|
||||
|
||||
Bugfixes:
|
||||
|
@ -1108,6 +1108,8 @@ public:
|
||||
bool leftAligned() const override { return underlyingType().leftAligned(); }
|
||||
bool canBeStored() const override { return underlyingType().canBeStored(); }
|
||||
u256 storageSize() const override { return underlyingType().storageSize(); }
|
||||
unsigned storageBytes() const override { return underlyingType().storageBytes(); }
|
||||
|
||||
bool isValueType() const override
|
||||
{
|
||||
solAssert(underlyingType().isValueType(), "");
|
||||
@ -1119,6 +1121,25 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool containsNestedMapping() const override
|
||||
{
|
||||
solAssert(nameable(), "Called for a non nameable type.");
|
||||
solAssert(!underlyingType().containsNestedMapping(), "");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasSimpleZeroValueInMemory() const override
|
||||
{
|
||||
solAssert(underlyingType().hasSimpleZeroValueInMemory(), "");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dataStoredIn(DataLocation _loc) const override
|
||||
{
|
||||
solAssert(!underlyingType().dataStoredIn(_loc), "");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string toString(bool _short) const override;
|
||||
std::string canonicalName() const override { solAssert(false, ""); }
|
||||
std::string signatureInExternalFunction(bool) const override { solAssert(false, ""); }
|
||||
|
1
test/cmdlineTests/storage_layout_user_defined/args
Normal file
1
test/cmdlineTests/storage_layout_user_defined/args
Normal file
@ -0,0 +1 @@
|
||||
--storage-layout
|
2
test/cmdlineTests/storage_layout_user_defined/err
Normal file
2
test/cmdlineTests/storage_layout_user_defined/err
Normal file
@ -0,0 +1,2 @@
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> storage_layout_user_defined/input.sol
|
16
test/cmdlineTests/storage_layout_user_defined/input.sol
Normal file
16
test/cmdlineTests/storage_layout_user_defined/input.sol
Normal file
@ -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;
|
||||
}
|
4
test/cmdlineTests/storage_layout_user_defined/output
Normal file
4
test/cmdlineTests/storage_layout_user_defined/output
Normal file
@ -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"}}}
|
@ -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
|
Loading…
Reference in New Issue
Block a user