This commit is contained in:
chriseth 2019-01-10 12:11:55 +01:00
parent 6de10cb9da
commit 44237211d1
19 changed files with 223 additions and 0 deletions

View File

@ -14234,6 +14234,70 @@ BOOST_AUTO_TEST_CASE(base_access_to_function_type_variables)
ABI_CHECK(callContractFunction("h()"), encodeArgs(2));
}
BOOST_AUTO_TEST_CASE(code_access)
{
char const* sourceCode = R"(
contract C {
function lengths() public pure returns (bool) {
uint crLen = type(D).creationCode.length;
uint runLen = type(D).runtimeCode.length;
require(runLen < crLen);
require(crLen >= 0x95 && crLen < 0xd0);
require(runLen >= 0x7a && runLen < 0xb0);
return true;
}
function creation() public pure returns (bytes memory) {
return type(D).creationCode;
}
function runtime() public pure returns (bytes memory) {
return type(D).runtimeCode;
}
function runtimeAllocCheck() public pure returns (bytes memory) {
uint[] memory a = new uint[](2);
bytes memory c = type(D).runtimeCode;
uint[] memory b = new uint[](2);
a[0] = 0x1111;
a[1] = 0x2222;
b[0] = 0x3333;
b[1] = 0x4444;
return c;
}
}
contract D {
function f() public pure returns (uint) { return 7; }
}
)";
compileAndRun(sourceCode, 0, "C");
ABI_CHECK(callContractFunction("lengths()"), encodeArgs(true));
bytes codeCreation = callContractFunction("creation()");
bytes codeRuntime1 = callContractFunction("runtime()");
bytes codeRuntime2 = callContractFunction("runtimeAllocCheck()");
ABI_CHECK(codeRuntime1, codeRuntime2);
}
BOOST_AUTO_TEST_CASE(code_access_create)
{
char const* sourceCode = R"(
contract C {
function test() public returns (uint) {
bytes memory c = type(D).creationCode;
D d;
assembly {
d := create(0, add(c, 0x20), mload(c))
}
return d.f();
}
}
contract D {
uint x;
constructor() public { x = 7; }
function f() public view returns (uint) { return x; }
}
)";
compileAndRun(sourceCode, 0, "C");
ABI_CHECK(callContractFunction("test()"), encodeArgs(7));
}
BOOST_AUTO_TEST_SUITE_END()
}

View File

@ -0,0 +1,12 @@
contract Test {
function creationOther() public pure returns (bytes memory) {
return type(Other).creationCode;
}
function runtimeOther() public pure returns (bytes memory) {
return type(Other).runtimeCode;
}
}
contract Other {
function f(uint) public pure returns (uint) {}
}
// ----

View File

@ -0,0 +1,10 @@
contract Test {
function creationOther() public pure returns (bytes memory) {
return type(Other).creationCode;
}
}
contract Other {
function f(uint) public returns (uint);
}
// ----
// TypeError: (97-121): Member "creationCode" not found or not visible after argument-dependent lookup in type(contract Other).

View File

@ -0,0 +1,10 @@
contract Test {
function runtime() public pure returns (bytes memory) {
return type(Other).runtimeCode;
}
}
contract Other {
function f(uint) public returns (uint);
}
// ----
// TypeError: (91-114): Member "runtimeCode" not found or not visible after argument-dependent lookup in type(contract Other).

View File

@ -0,0 +1,22 @@
contract Base {
function f() public pure returns (uint) {}
}
contract Test is Base {
function creation() public pure returns (bytes memory) {
return type(Test).creationCode;
}
function runtime() public pure returns (bytes memory) {
return type(Test).runtimeCode;
}
function creationBase() public pure returns (bytes memory) {
return type(Base).creationCode;
}
function runtimeBase() public pure returns (bytes memory) {
return type(Base).runtimeCode;
}
}
// ----
// TypeError: (165-188): Circular reference for contract code access.
// TypeError: (271-293): Circular reference for contract code access.
// TypeError: (381-404): Circular reference for contract code access.
// TypeError: (491-513): Circular reference for contract code access.

View File

@ -0,0 +1,12 @@
contract A {
function f() public pure {
type(B).runtimeCode;
}
}
contract B {
function f() public pure {
type(A).runtimeCode;
}
}
// ----
// TypeError: (133-152): Circular reference for contract code access.

View File

@ -0,0 +1,7 @@
contract Test {
bytes constant c = type(B).creationCode;
bytes constant r = type(B).runtimeCode;
}
contract B { function f() public pure {} }
// ----

View File

@ -0,0 +1,12 @@
contract Test {
function creationOther() public pure returns (bytes memory) {
return type(Library).creationCode;
}
function runtime() public pure returns (bytes memory) {
return type(Library).runtimeCode;
}
}
contract Library {
function f(uint) public pure returns (uint) {}
}
// ----

View File

@ -0,0 +1,10 @@
contract Test {
function f() public pure {
type(C).creationCode = new bytes(6);
type(C).runtimeCode = new bytes(6);
}
}
contract C {}
// ----
// TypeError: (55-75): Expression has to be an lvalue.
// TypeError: (100-119): Expression has to be an lvalue.

View File

@ -0,0 +1,7 @@
contract Test {
function creation() public pure returns (bytes memory) {
type();
}
}
// ----
// TypeError: (85-91): This function takes one argument, but 0 were provided.

View File

@ -0,0 +1,7 @@
contract Test {
function creation() public pure returns (bytes memory) {
type(1, 2);
}
}
// ----
// TypeError: (85-95): This function takes one argument, but 2 were provided.

View File

@ -0,0 +1,3 @@
contract type { }
// ----
// ParserError: (9-13): Expected identifier but got 'type'

View File

@ -0,0 +1,6 @@
contract Test {
function type() public pure {
}
}
// ----
// ParserError: (29-33): Expected identifier but got 'type'

View File

@ -0,0 +1,6 @@
contract Test {
function f(uint type) public pure {
}
}
// ----
// ParserError: (36-40): Expected ',' but got 'type'

View File

@ -0,0 +1,5 @@
contract Test {
uint type;
}
// ----
// ParserError: (25-29): Expected identifier but got 'type'

View File

@ -0,0 +1,7 @@
contract Test {
function f() public pure {
uint type;
}
}
// ----
// ParserError: (60-64): Expected ';' but got 'type'

View File

@ -0,0 +1,6 @@
contract Test {
function f() public pure returns (bytes memory) {
type(Test);
}
}
// ----

View File

@ -0,0 +1,8 @@
contract Test {
function f() public pure {
type(type(type(Test)));
}
}
// ----
// TypeError: (65-75): Invalid type for argument in function call. Contract type required, but type(contract Test) provided.
// TypeError: (60-76): Invalid type for argument in function call. Contract type required, but tuple() provided.

View File

@ -0,0 +1,9 @@
contract Test {
struct S { uint x; }
function f() public pure {
// Unsupported for now, but might be supported in the future
type(S);
}
}
// ----
// TypeError: (154-155): Invalid type for argument in function call. Contract type required, but type(struct Test.S) provided.