IR codegen: Handle address() with library type argument and external library calls

This commit is contained in:
Kamil Śliwak
2020-11-17 20:36:39 +01:00
parent e1292380bd
commit dfa0a0cdff
13 changed files with 226 additions and 7 deletions
@@ -16,6 +16,8 @@ contract C {
return fu();
}
}
// ====
// compileViaYul: also
// ----
// library: L
// f() -> 7, 8
// f() -> 7, 8
@@ -0,0 +1,26 @@
library L {
function run(
function(uint256) external returns (uint256) _operation,
uint256 _a
)
external
returns (uint256)
{
return _operation(_a);
}
}
contract C {
function double(uint256 _a) external returns (uint256) {
return _a * _a;
}
function g(uint256 _value) external returns (uint256) {
return L.run(this.double, _value);
}
}
// ====
// compileViaYul: also
// ----
// library: L
// g(uint256): 4 -> 16
@@ -0,0 +1,19 @@
library L {
function f(uint256[2] storage _a) external returns (uint256) {
return _a[0] * _a[1];
}
}
contract C {
uint256[2] x;
function g(uint256 _value) external returns (uint256) {
x[0] = x[1] = _value;
return L.f(x);
}
}
// ====
// compileViaYul: also
// ----
// library: L
// g(uint256): 4 -> 16
@@ -12,6 +12,8 @@ contract C {
return success;
}
}
// ====
// compileViaYul: also
// ----
// library: L
// g(uint256,uint256): 1, 1 -> true
@@ -0,0 +1,60 @@
==== Source: a.sol ====
import "a.sol" as M;
library L {
function f(uint256 v) external pure returns (uint) {
return v * v;
}
function g(uint256 v) external returns (uint) {
return v * v;
}
}
contract C {
function addr() public view returns (bool) {
return address(M.L) == address(0);
}
function g(uint256 v) public view returns (uint256) {
return M.L.f(v);
}
function h(uint256 v) public returns (uint256) {
(bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature("f(uint256)", v));
assert(success);
return abi.decode(result, (uint256));
}
function i(uint256 v) public returns (uint256) {
(bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature("f(uint256)", v));
assert(success);
return abi.decode(result, (uint256));
}
function j(uint256 v) public returns (uint256) {
(bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature("g(uint256)", v));
assert(success);
return abi.decode(result, (uint256));
}
function k(uint256 v) public returns (uint256) {
(bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature("g(uint256)", v));
assert(success);
return abi.decode(result, (uint256));
}
}
// ====
// EVMVersion: >=byzantium
// ----
// library: L
// addr() -> false
// g(uint256): 1 -> 1
// g(uint256): 2 -> 4
// g(uint256): 4 -> 16
// h(uint256): 1 -> 1
// h(uint256): 2 -> 4
// h(uint256): 4 -> 16
// i(uint256): 1 -> 1
// i(uint256): 2 -> 4
// i(uint256): 4 -> 16
// j(uint256): 1 -> 1
// j(uint256): 2 -> 4
// j(uint256): 4 -> 16
// k(uint256): 1 -> FAILURE
// k(uint256): 2 -> FAILURE
// k(uint256): 4 -> FAILURE
@@ -6,6 +6,8 @@ contract C {
return L.f(v);
}
}
// ====
// compileViaYul: also
// ----
// library: L
// g(uint256): 1 -> 1
@@ -0,0 +1,14 @@
library L {
function f(uint256 _a) external returns (uint256) {}
}
contract C {
function run(function(uint256) external returns (uint256) _operation) internal returns (uint256) {}
function test() public {
run(L.f);
function(uint256) external returns (uint256) _operation = L.f;
}
}
// ----
// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) returns (uint256) to function (uint256) external returns (uint256) requested.
// TypeError 9574: (244-305): Type function (uint256) returns (uint256) is not implicitly convertible to expected type function (uint256) external returns (uint256).
@@ -0,0 +1,21 @@
interface I {}
library L {}
contract C {
function f() public pure {
address(C);
address(I);
address(L); // This one is allowed
address(type(C));
address(type(I));
address(type(L));
}
}
// ----
// TypeError 9640: (82-92): Explicit type conversion not allowed from "type(contract C)" to "address".
// TypeError 9640: (102-112): Explicit type conversion not allowed from "type(contract I)" to "address".
// TypeError 9640: (166-182): Explicit type conversion not allowed from "type(contract C)" to "address".
// TypeError 9640: (192-208): Explicit type conversion not allowed from "type(contract I)" to "address".
// TypeError 9640: (218-234): Explicit type conversion not allowed from "type(library L)" to "address".
@@ -0,0 +1,7 @@
contract C {
function f() public pure {
address(super);
}
}
// ----
// TypeError 9640: (52-66): Explicit type conversion not allowed from "contract super C" to "address".
@@ -0,0 +1,46 @@
struct S {
uint x;
}
enum E {A, B, C}
contract C {
function f() public pure {
address(uint);
address(bytes16);
address(bool);
address(address);
address(fixed);
address(S);
address(E);
address(uint[]);
address(uint[][]);
address(uint[5]);
address(string);
address(bytes);
address(S[]);
address(E[]);
address((uint, uint));
address(type(uint));
}
}
// ----
// TypeError 9640: (96-109): Explicit type conversion not allowed from "type(uint256)" to "address".
// TypeError 9640: (119-135): Explicit type conversion not allowed from "type(bytes16)" to "address".
// TypeError 9640: (145-158): Explicit type conversion not allowed from "type(bool)" to "address".
// TypeError 9640: (168-184): Explicit type conversion not allowed from "type(address)" to "address".
// TypeError 9640: (194-208): Explicit type conversion not allowed from "type(fixed128x18)" to "address".
// TypeError 9640: (219-229): Explicit type conversion not allowed from "type(struct S storage pointer)" to "address".
// TypeError 9640: (239-249): Explicit type conversion not allowed from "type(enum E)" to "address".
// TypeError 9640: (260-275): Explicit type conversion not allowed from "type(uint256[] memory)" to "address".
// TypeError 9640: (285-302): Explicit type conversion not allowed from "type(uint256[] memory[] memory)" to "address".
// TypeError 9640: (312-328): Explicit type conversion not allowed from "type(uint256[5] memory)" to "address".
// TypeError 9640: (338-353): Explicit type conversion not allowed from "type(string storage pointer)" to "address".
// TypeError 9640: (363-377): Explicit type conversion not allowed from "type(bytes storage pointer)" to "address".
// TypeError 9640: (387-399): Explicit type conversion not allowed from "type(struct S memory[] memory)" to "address".
// TypeError 9640: (409-421): Explicit type conversion not allowed from "type(enum E[] memory)" to "address".
// TypeError 9640: (431-452): Explicit type conversion not allowed from "tuple(type(uint256),type(uint256))" to "address".
// TypeError 9640: (463-482): Explicit type conversion not allowed from "type(uint256)" to "address".