Merge remote-tracking branch 'origin/develop' into breaking

This commit is contained in:
chriseth
2020-12-01 10:50:13 +01:00
81 changed files with 1740 additions and 775 deletions
-24
View File
@@ -4384,30 +4384,6 @@ BOOST_AUTO_TEST_CASE(non_payable_throw)
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
}
BOOST_AUTO_TEST_CASE(no_nonpayable_circumvention_by_modifier)
{
char const* sourceCode = R"(
contract C {
modifier tryCircumvent {
if (false) _; // avoid the function, we should still not accept ether
}
function f() tryCircumvent public returns (uint) {
return msgvalue();
}
function msgvalue() internal returns (uint) {
return msg.value;
}
}
)";
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs());
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
)
}
BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call)
{
// This tests that memory resize for return values is not paid during the call, which would
@@ -0,0 +1,19 @@
contract c {
uint64[] data1;
uint256[] data2;
function test() public returns (uint256 x, uint256 y) {
data2.push(11);
data1.push(0);
data1.push(1);
data1.push(2);
data1.push(3);
data1.push(4);
data2 = data1;
assert(data1[0] == data2[0]);
x = data2.length;
y = data2[4];
}
}
// ----
// test() -> 5, 4
@@ -0,0 +1,22 @@
contract c {
uint256[] data1;
uint256[] data2;
function test() public returns (uint256 x, uint256 y) {
data2.push(11);
data1.push(0);
data1.push(1);
data1.push(2);
data1.push(3);
data1.push(4);
data2 = data1;
assert(data1[0] == data2[0]);
x = data2.length;
y = data2[4];
}
}
// ====
// compileViaYul: also
// ----
// test() -> 5, 4
@@ -13,5 +13,7 @@ contract c {
}
}
// ====
// compileViaYul: also
// ----
// test() -> 8, 0
@@ -30,7 +30,7 @@ contract c {
}
}
// ====
// compileViaYul: true
// compileViaYul: also
// ----
// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65
// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65
@@ -18,6 +18,6 @@ contract C {
}
}
// ====
// compileViaYul: true
// compileViaYul: also
// ----
// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1
@@ -0,0 +1,14 @@
pragma abicoder v2;
contract C {
function g(bytes[2] memory m) internal returns (bytes memory) {
return m[0];
}
function f(bytes[2] calldata c) external returns (bytes memory) {
return g(c);
}
}
// ====
// compileViaYul: also
// ----
// f(bytes[2]): 0x20, 0x40, 0x40, 2, "ab" -> 0x20, 2, "ab"
@@ -0,0 +1,18 @@
pragma abicoder v2;
contract C {
function g(bytes[2] memory m) internal {
assert(m[0].length > 1);
assert(m[1].length > 1);
assert(m[0][0] == m[1][0]);
assert(m[0][1] == m[1][1]);
}
function f(bytes[2] calldata c) external {
g(c);
}
}
// ====
// compileViaYul: also
// ----
// f(bytes[2]): 0x20, 0x40, 0x40, 2, "ab" ->
// f(bytes[2]): 0x20, 0x40, 0x40, 1, "a" -> FAILURE
@@ -0,0 +1,14 @@
pragma abicoder v2;
contract Test {
struct shouldBug {
uint256[][2] deadly;
}
function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {
return shouldBug(weapon);
}
}
// ====
// compileViaYul: also
// ----
// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2
@@ -11,10 +11,23 @@ contract C {
function f() public m returns (bool) {
return true;
}
modifier n {
uint256 a = 1;
assembly {
a := 2
}
if (a != 2)
_;
revert();
}
function g() public n returns (bool) {
// This statement should never execute.
return true;
}
}
// ====
// compileViaYul: also
// compileToEwasm: also
// ----
// f() -> true
// g() -> FAILURE
@@ -3,7 +3,8 @@ contract C {
modifier run() {
for (uint256 i = 0; i < 10; i++) {
_;
break;
if (i == 1)
break;
}
}
@@ -13,10 +14,7 @@ contract C {
x = t;
}
}
// ====
// compileViaYul: also
// compileToEwasm: also
// ----
// x() -> 0
// f() ->
// x() -> 1
// x() -> 2
@@ -1,22 +1,21 @@
contract C {
uint256 public x;
modifier run() {
modifier m() {
for (uint256 i = 0; i < 10; i++) {
_;
break;
++x;
return;
}
}
function f() public run {
uint256 k = x;
uint256 t = k + 1;
x = t;
function f() public m m m returns (uint) {
for (uint256 i = 0; i < 10; i++) {
++x;
return 42;
}
}
}
// ====
// compileViaYul: also
// compileToEwasm: also
// ----
// x() -> 0
// f() ->
// x() -> 1
// f() -> 42
// x() -> 4
@@ -0,0 +1,18 @@
contract C {
modifier tryCircumvent {
if (false) _; // avoid the function, we should still not accept ether
}
function f() tryCircumvent public returns (uint) {
return msgvalue();
}
function msgvalue() internal returns (uint) {
return msg.value;
}
// TODO: remove this helper function once isoltest supports balance checking
function balance() external returns (uint) {
return address(this).balance;
}
}
// ----
// f(), 27 wei -> FAILURE
// balance() -> 0
@@ -1,4 +1,4 @@
pragma abicoder v2;
pragma abicoder v2;
contract C {
@@ -19,6 +19,7 @@ contract C {
c = s.c;
}
}
// ====
// compileViaYul: also
// ----
// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23
@@ -0,0 +1,24 @@
pragma abicoder v2;
contract C {
struct S {
uint32 a;
uint256[] b;
uint64 c;
}
function f(S calldata s)
external
pure
returns (uint32 a, uint256 b0, uint256 b1, uint64 c)
{
a = s.a;
b0 = s.b[0];
b1 = s.b[1];
c = s.c;
}
}
// ====
// compileViaYul: also
// ----
// f((uint32,uint256[],uint64)): 0x20, 42, 0x60, 23, 2, 1, 2 -> 42, 1, 2, 23
@@ -0,0 +1,28 @@
pragma abicoder v2;
contract C {
struct S {
uint64 a;
uint64 b;
}
struct S1 {
uint256 a;
S s;
uint256 c;
}
function f(S1 calldata s1)
external
pure
returns (uint256 a, uint64 b0, uint64 b1, uint256 c)
{
a = s1.a;
b0 = s1.s.a;
b1 = s1.s.b;
c = s1.c;
}
}
// ====
// compileViaYul: also
// ----
// f((uint256,(uint64, uint64),uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23
@@ -0,0 +1,28 @@
pragma abicoder v2;
contract C {
struct S {
uint64 a;
bytes b;
}
struct S1 {
uint256 a;
S s;
uint256 c;
}
function f(S1 calldata s1)
external
pure
returns (uint256 a, uint64 b0, byte b1, uint256 c)
{
a = s1.a;
b0 = s1.s.a;
b1 = s1.s.b[0];
c = s1.c;
}
}
// ====
// compileViaYul: also
// ----
// f((uint256,(uint64, bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, "ab" -> 42, 1, "a", 23
@@ -15,5 +15,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// f() -> true
@@ -22,5 +22,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5
@@ -0,0 +1,87 @@
contract C {
function conv(bytes25 a) public pure returns (bytes32) {
// truncating and widening
return ~bytes32(bytes16(~a));
}
function upcast(bytes25 a) public pure returns (bytes32) {
// implicit widening is allowed
return ~a;
}
function downcast(bytes25 a) public pure returns (bytes12) {
// truncating cast must be explicit
return bytes12(~a);
}
function r_b32() public pure returns (bytes32) {
return ~bytes32(hex"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00");
}
function r_b25() public pure returns (bytes25) {
return ~bytes25(hex"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff");
}
function r_b16() public pure returns (bytes16) {
return ~bytes16(hex"ff00ff00ff00ff00ff00ff00ff00ff00");
}
function r_b8() public pure returns (bytes8) {
return ~bytes8(hex"ff00ff00ff00ff00");
}
function r_b4() public pure returns (bytes4) {
return ~bytes4(hex"ff00ff00");
}
function r_b1() public pure returns (bytes1) {
return ~bytes1(hex"55");
}
function r_b() public pure returns (byte) {
return ~byte(hex"55");
}
function a_b32() public pure returns (bytes32) {
bytes32 r = ~bytes32(hex"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00");
return r;
}
function a_b25() public pure returns (bytes25) {
bytes25 r = ~bytes25(hex"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff");
return r;
}
function a_b16() public pure returns (bytes16) {
bytes16 r = ~bytes16(hex"ff00ff00ff00ff00ff00ff00ff00ff00");
return r;
}
function a_b8() public pure returns (bytes8) {
bytes8 r = ~bytes8(hex"ff00ff00ff00ff00");
return r;
}
function a_b4() public pure returns (bytes4) {
bytes4 r = ~bytes4(hex"ff00ff00");
return r;
}
function a_b1() public pure returns (byte) {
bytes1 r = ~bytes1(hex"55");
return r;
}
function a_b() public pure returns (byte) {
byte r = ~byte(hex"55");
return r;
}
}
// ====
// compileViaYul: also
// ----
// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff
// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000
// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000
// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff
// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000
// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000
// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000
// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000
// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000
// r_b() -> 0xaa00000000000000000000000000000000000000000000000000000000000000
// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff
// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000
// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000
// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000
// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000
// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000
// a_b() -> 0xaa00000000000000000000000000000000000000000000000000000000000000
@@ -0,0 +1,28 @@
pragma experimental SMTChecker;
contract C {
uint x;
modifier check() {
require(x == 0);
_;
assert(x == 1); // should fail;
assert(x == 0); // should hold;
}
modifier inc() {
if (x == 0) {
return;
}
x = x + 1;
_;
}
function test() check inc public {
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (103-117): BMC: Assertion violation happens here.
@@ -0,0 +1,45 @@
pragma experimental SMTChecker;
contract C {
uint x;
function reset_if_overflow() internal postinc {
if (x < 10)
return;
x = 0;
}
modifier postinc() {
if (x == 0) {
return;
}
_;
x = x + 1;
}
function test() public {
if (x == 0) {
reset_if_overflow();
assert(x == 1); // should fail;
assert(x == 0); // should hold;
return;
}
if (x < 10) {
uint oldx = x;
reset_if_overflow();
assert(oldx + 1 == x); // should hold;
assert(oldx == x); // should fail;
return;
}
reset_if_overflow();
assert(x == 1); // should hold;
assert(x == 0); // should fail;
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (384-398): BMC: Assertion violation happens here.
// Warning 4661: (635-652): BMC: Assertion violation happens here.
// Warning 4661: (781-795): BMC: Assertion violation happens here.
@@ -0,0 +1,43 @@
pragma experimental SMTChecker;
contract A {
int x;
constructor (int a) { x = a;}
}
contract B is A {
int y;
constructor(int a) A(-a) {
if (a > 0) {
y = 2;
return;
}
else {
y = 3;
}
y = 4; // overwrites the else branch
}
}
contract C is B {
constructor(int a) B(a) {
assert(y != 3); // should hold
assert(y == 4); // should fail
if (a > 0) {
assert(x < 0 && y == 2); // should hold
assert(x < 0 && y == 4); // should fail
}
else {
assert(x >= 0 && y == 4); // should hold
assert(x >= 0 && y == 2); // should fail
assert(x > 0); // should fail
}
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (330-344): BMC: Assertion violation happens here.
// Warning 4661: (422-445): BMC: Assertion violation happens here.
// Warning 4661: (522-546): BMC: Assertion violation happens here.
// Warning 4661: (566-579): BMC: Assertion violation happens here.
@@ -0,0 +1,30 @@
pragma experimental SMTChecker;
contract A {
uint x = 1;
}
contract B is A {
constructor(int a) {
if (a > 0) {
x = 2;
return;
}
x = 3;
}
}
abstract contract C is B {
}
contract D is C {
constructor(int a) B(a) {
assert(a > 0 || x == 3); // should hold
assert(a <= 0 || x == 2); // should hold
assert(x == 1); // should fail
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (319-333): BMC: Assertion violation happens here.
@@ -0,0 +1,72 @@
pragma experimental SMTChecker;
contract A {
int x;
}
contract B is A {
int y;
constructor (int a) {
if (a >= 0) {
y = 1;
return;
}
x = 1;
y = 2;
}
}
contract C is A {
int z;
constructor (int a) {
if (a >= 0) {
z = 1;
return;
}
x = -1;
z = 2;
}
}
contract D1 is B, C {
constructor() B(1) C(1) {
assert(x == 0); // should hold
assert(x == 1); // should fail
assert(x == -1); // should fail
}
}
contract D2 is B, C {
constructor() B(1) C(-1) {
assert(x == 0); // should fail
assert(x == 1); // should fail
assert(x == -1); // should hold (constructor of C is executed AFTER constructor of B)
}
}
contract D3 is B, C {
constructor() B(-1) C(1) {
assert(x == 0); // should fail
assert(x == 1); // should hold
assert(x == -1); // should fail
}
}
contract D4 is B, C {
constructor() B(-1) C(-1) {
assert(x == 0); // should fail
assert(x == 1); // should fail
assert(x == -1); // should hold (constructor of C is executed AFTER constructor of B)
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (370-384): BMC: Assertion violation happens here.
// Warning 4661: (403-418): BMC: Assertion violation happens here.
// Warning 4661: (493-507): BMC: Assertion violation happens here.
// Warning 4661: (526-540): BMC: Assertion violation happens here.
// Warning 4661: (703-717): BMC: Assertion violation happens here.
// Warning 4661: (769-784): BMC: Assertion violation happens here.
// Warning 4661: (860-874): BMC: Assertion violation happens here.
// Warning 4661: (893-907): BMC: Assertion violation happens here.
@@ -0,0 +1,33 @@
pragma experimental SMTChecker;
contract B {
int x;
constructor(int b) {
if (b > 0) {
x = 1;
return;
}
else {
x = 2;
return;
}
x = 3; // dead code
}
}
contract C is B {
constructor(int a) B(a) {
assert(a > 0 || x == 2); // should hold
assert(a <= 0 || x == 1); // should hold
assert(x == 3); // should fail
assert(x == 2); // should fail
assert(x == 1); // should fail
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 5740: (152-157): Unreachable code.
// Warning 4661: (310-324): BMC: Assertion violation happens here.
// Warning 4661: (343-357): BMC: Assertion violation happens here.
// Warning 4661: (376-390): BMC: Assertion violation happens here.
@@ -0,0 +1,28 @@
pragma experimental SMTChecker;
contract C {
function test(uint256 a, uint256 b) public pure {
assert(nested_if(a,b) != 42); // should hold
assert(nested_if(a,b) == 1); // should fail
}
function nested_if(uint256 a, uint256 b) internal pure returns (uint256) {
if (a < 5) {
if (b > 1) {
return 0;
}
}
if (a == 2 && b == 2) {
return 42; // unreachable
}
else {
return 1;
}
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (147-174): BMC: Assertion violation happens here.
// Warning 6838: (332-348): BMC: Condition is always false.
@@ -0,0 +1,23 @@
pragma experimental SMTChecker;
contract C {
function test() public pure {
assert(branches(0) == 0);
assert(branches(1) == 42);
}
function branches(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
else {
return 42;
}
return 1; // dead code
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 5740: (265-273): Unreachable code.
@@ -0,0 +1,13 @@
pragma experimental SMTChecker;
contract C {
function test(uint256 a, uint256 b) public pure returns (uint256) {
if (a == 0) {
return 0;
}
return b / a; // This division is safe because of the early return in if-block.
}
}
// ====
// SMTEngine: bmc
// ----
@@ -0,0 +1,19 @@
pragma experimental SMTChecker;
contract C {
function test(uint256 a) public pure {
assert(simple_if(a) == 1); // should fail for a == 0
}
function simple_if(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
return 1;
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (89-114): BMC: Assertion violation happens here.
@@ -0,0 +1,30 @@
pragma experimental SMTChecker;
contract C {
uint[] a;
constructor () {
a.push();
a.push();
}
function check() public {
require(a.length >= 2);
require(a[1] == 0);
conditional_store();
assert(a[1] == 1); // should fail;
assert(a[1] == 0); // should hold;
}
function conditional_store() internal {
if (a[1] == 0) {
return;
}
a[1] = 1;
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (205-222): BMC: Assertion violation happens here.
@@ -0,0 +1,24 @@
pragma experimental SMTChecker;
contract C {
uint x;
function check() public {
require(x == 0);
conditional_increment();
assert(x == 1); // should fail;
assert(x == 0); // should hold;
}
function conditional_increment() internal {
if (x == 0) {
return;
}
x = 1;
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (132-146): BMC: Assertion violation happens here.
@@ -0,0 +1,27 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
}
S s;
function check() public {
require(s.x == 0);
conditional_increment();
assert(s.x == 1); // should fail;
assert(s.x == 0); // should hold;
}
function conditional_increment() internal {
if (s.x == 0) {
return;
}
s.x = 1;
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (156-172): BMC: Assertion violation happens here.
@@ -0,0 +1,27 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
}
S s;
function check() public {
require(s.x == 0);
conditional_increment();
assert(s.x == 1); // should fail;
assert(s.x == 0); // should hold;
}
function conditional_increment() internal {
if (s.x == 0) {
return;
}
s = S(1);
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (156-172): BMC: Assertion violation happens here.
@@ -0,0 +1,29 @@
pragma experimental SMTChecker;
contract C {
uint x;
uint y;
function check() public {
require(x == 0);
require(y == 0);
conditional_increment();
assert(x == 0); // should fail;
assert(x == 1); // should fail;
assert(x == 2); // should hold;
}
function conditional_increment() internal {
if (x == 0) {
(x,y) = (2,2);
return;
}
(x,y) = (1,1);
}
}
// ====
// SMTEngine: bmc
// ----
// Warning 4661: (160-174): BMC: Assertion violation happens here.
// Warning 4661: (194-208): BMC: Assertion violation happens here.
@@ -0,0 +1,22 @@
pragma experimental SMTChecker;
contract C {
uint a;
uint b;
uint c;
function test() public view {
if (a == 0) {
if (b == 0) {
if (c == 0) {
return;
}
}
}
assert(a != 0 || b != 0 || c != 0);
}
}
// ====
// SMTEngine: bmc
// ----
@@ -1,14 +1,14 @@
pragma experimental SMTChecker;
contract C {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
function mul(uint256 a, uint256 b) public pure returns (uint256) {
if (a == 0) {
return 0;
}
// TODO remove when SMTChecker sees that this code is the `else` of the `return`.
require(a != 0);
uint256 c = a * b;
require(c / a == b);
return c;
}
}
// ----
// Warning 4984: (160-165): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.
// Warning 4281: (177-182): CHC: Division by zero happens here.
@@ -0,0 +1,9 @@
contract C {
byte[32] data1;
bytes2[10] data2;
function f() external {
data1 = data2;
}
}
// ----
// TypeError 7407: (99-104): Type bytes2[10] storage ref is not implicitly convertible to expected type bytes1[32] storage ref.
@@ -0,0 +1,9 @@
contract C {
uint64[32] data1;
uint256[10] data2;
function f() external {
data1 = data2;
}
}
// ----
// TypeError 7407: (102-107): Type uint256[10] storage ref is not implicitly convertible to expected type uint64[32] storage ref.
@@ -0,0 +1,9 @@
contract C {
uint256[10] data1;
uint256[] data2;
function f() external {
data1 = data2;
}
}
// ----
// TypeError 7407: (101-106): Type uint256[] storage ref is not implicitly convertible to expected type uint256[10] storage ref.
@@ -0,0 +1,9 @@
contract C {
uint256[10] data1;
uint256[18] data2;
function f() external {
data1 = data2;
}
}
// ----
// TypeError 7407: (103-108): Type uint256[18] storage ref is not implicitly convertible to expected type uint256[10] storage ref.
@@ -10,4 +10,3 @@ contract Test {
}
// ----
// UnimplementedFeatureError: Copying nested dynamic calldata arrays to memory is not implemented in the old code generator.
@@ -10,4 +10,3 @@ contract Test {
}
// ----
// UnimplementedFeatureError: Copying nested dynamic calldata arrays to memory is not implemented in the old code generator.
@@ -10,4 +10,3 @@ contract Test {
}
// ----
// UnimplementedFeatureError: Copying nested dynamic calldata arrays to memory is not implemented in the old code generator.
@@ -0,0 +1,5 @@
contract C {
bytes32 b32 = ~bytes32(hex"ff");
bytes32 b25 = ~bytes25(hex"ff");
bytes25 b8 = ~bytes8(hex"ff");
}
@@ -0,0 +1,5 @@
contract C {
bytes32 b = ~hex"00ff11";
}
// ----
// TypeError 4907: (29-41): Unary operator ~ cannot be applied to type literal_string hex"00ff11"