[Sol->Yul] Disable old codegen test viaYul and create new one that fits IR semantics.

Co-authored-by: chriseth <chris@ethereum.org>
This commit is contained in:
Djordje Mijovic 2020-12-22 10:55:40 +01:00
parent 6bcae84610
commit a204596c3e
3 changed files with 44 additions and 0 deletions

View File

@ -90,3 +90,27 @@ This causes differences in some contracts, for example:
Previously, ``y`` would be set to 0. This is due to the fact that we would first initialize state variables: First, ``x`` is set to 0, and when initializing ``y``, ``f()`` would return 0 causing ``y`` to be 0 as well. Previously, ``y`` would be set to 0. This is due to the fact that we would first initialize state variables: First, ``x`` is set to 0, and when initializing ``y``, ``f()`` would return 0 causing ``y`` to be 0 as well.
With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, then call A's constructor which sets ``x`` to 42. Finally, when initializing ``y``, ``f()`` returns 42 causing ``y`` to be 42. With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, then call A's constructor which sets ``x`` to 42. Finally, when initializing ``y``, ``f()`` returns 42 causing ``y`` to be 42.
* Copying `bytes` arrays from memory to storage is implemented in a different way. The old code generator always copies full words, while the new one cuts the byte array after its end. The old behaviour can lead to dirty data being copied after the end of the array (but still in the same storage slot).
This causes differences in some contracts, for example:
::
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.8.0;
contract C {
bytes x;
function f() public returns (uint r) {
bytes memory m = "tmp";
assembly {
mstore(m, 8)
mstore(add(m, 32), "deadbeef15dead")
}
x = m;
assembly {
r := sload(x.slot)
}
}
}
Previously `f()` would return `0x6465616462656566313564656164000000000000000000000000000000000010` (it has correct length, and correct first 8 elements, but than it contains dirty data which was set via assembly).
Now it is returning `0x6465616462656566000000000000000000000000000000000000000000000010` (it has correct length, and correct elements, but doesn't contain dirty data).

View File

@ -12,5 +12,7 @@ contract C {
} }
} }
} }
// ====
// compileViaYul: false
// ---- // ----
// f() -> 0x6465616462656566313564656164000000000000000000000000000000000010 // f() -> 0x6465616462656566313564656164000000000000000000000000000000000010

View File

@ -0,0 +1,18 @@
contract C {
bytes x;
function f() public returns (uint r) {
bytes memory m = "tmp";
assembly {
mstore(m, 8)
mstore(add(m, 32), "deadbeef15dead")
}
x = m;
assembly {
r := sload(x.slot)
}
}
}
// ====
// compileViaYul: true
// ----
// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010