Free functions.

This commit is contained in:
chriseth
2020-08-18 11:46:59 +02:00
parent 660ef792ab
commit 9324fb4f20
51 changed files with 481 additions and 73 deletions
@@ -0,0 +1,13 @@
function add(uint a, uint b) pure returns (uint) {
return a + b;
}
contract C {
function f(uint x) public pure returns (uint) {
return add(x, 2);
}
}
// ====
// compileViaYul: also
// ----
// f(uint256): 7 -> 9
@@ -0,0 +1,15 @@
contract C {
uint public x = 2;
}
function test() returns (bool) {
return type(C).runtimeCode.length > 20;
}
contract D {
function f() public returns (bool) {
return test();
}
}
// ----
// f() -> true
@@ -0,0 +1,18 @@
==== Source: A ====
struct S { uint x; }
function set(S storage a, uint v) { a.x = v; }
==== Source: B ====
import "A";
import "A" as A;
contract C {
A.S data;
function f(uint v) public returns (uint one, uint two) {
A.set(data, v);
one = data.x;
set(data, v + 1);
two = data.x;
}
}
// ----
// f(uint256): 7 -> 7, 8
@@ -0,0 +1,21 @@
library L {
function pub() public pure returns (uint) {
return 7;
}
function inter() internal pure returns (uint) {
return 8;
}
}
function fu() pure returns (uint, uint) {
return (L.pub(), L.inter());
}
contract C {
function f() public pure returns (uint, uint) {
return fu();
}
}
// ----
// library: L
// f() -> 7, 8
@@ -0,0 +1,15 @@
contract C {
uint public x = 2;
}
function test() returns (uint) {
return (new C()).x();
}
contract D {
function f() public returns (uint) {
return test();
}
}
// ----
// f() -> 2
@@ -0,0 +1,16 @@
function f(uint) returns (uint) {
return 2;
}
function f(string memory) returns (uint) {
return 3;
}
contract C {
function g() public returns (uint, uint) {
return (f(2), f("abc"));
}
}
// ====
// compileViaYul: also
// ----
// g() -> 2, 3
@@ -0,0 +1,23 @@
function exp(uint base, uint exponent) pure returns (uint power) {
if (exponent == 0)
return 1;
power = exp(base, exponent / 2);
power *= power;
if (exponent & 1 == 1)
power *= base;
}
contract C {
function g(uint base, uint exponent) public pure returns (uint) {
return exp(base, exponent);
}
}
// ====
// compileViaYul: also
// ----
// g(uint256,uint256): 0, 0 -> 1
// g(uint256,uint256): 0, 1 -> 0x00
// g(uint256,uint256): 1, 0 -> 1
// g(uint256,uint256): 2, 3 -> 8
// g(uint256,uint256): 3, 10 -> 59049
// g(uint256,uint256): 2, 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968
@@ -0,0 +1,17 @@
contract C {
uint[] data;
function f(uint x, uint[] calldata input) public returns (uint, uint) {
data.push(x);
(uint a, uint[] calldata b) = fun(input, data);
return (a, b[1]);
}
}
function fun(uint[] calldata _x, uint[] storage _y) view returns (uint, uint[] calldata) {
return (_y[0], _x);
}
// ====
// compileViaYul: also
// ----
// f(uint256,uint256[]): 7, 0x40, 3, 8, 9, 10 -> 7, 9
@@ -0,0 +1,8 @@
contract C {
function f() public pure {}
}
function fun() {
C.f();
}
// ----
// TypeError 3419: (68-73): Cannot call function via contract type name.
@@ -0,0 +1,3 @@
constructor() {}
// ----
// ParserError 7858: (0-11): Expected pragma, import directive or contract/interface/library/struct/enum/function definition.
@@ -0,0 +1,3 @@
fallback(){}
// ----
// ParserError 7858: (0-8): Expected pragma, import directive or contract/interface/library/struct/enum/function definition.
@@ -0,0 +1,4 @@
function fun() someModifier {
}
// ----
// DeclarationError 7576: (15-27): Undeclared identifier.
@@ -0,0 +1,9 @@
contract C {
modifier someModifier() { _; }
}
function fun() C.someModifier {
}
// ----
// ParserError 2314: (65-66): Expected '{' but got '.'
@@ -0,0 +1,9 @@
function f() {}
contract C {
function f() public {}
function g() public {
f();
}
}
// ----
// Warning 2519: (31-53): This declaration shadows an existing declaration.
@@ -0,0 +1,5 @@
function fun1() public { }
function fun2() internal { }
// ----
// SyntaxError 4126: (0-26): Free functions cannot have visibility.
// SyntaxError 4126: (27-55): Free functions cannot have visibility.
@@ -0,0 +1,3 @@
function f();
// ----
// TypeError 4668: (0-13): Free functions must be implemented.
@@ -0,0 +1,4 @@
function fun(uint256, uint[] calldata _x, uint[] storage _y) view returns (uint, uint[] calldata) {
return (_y[0], _x);
}
// ----
@@ -0,0 +1,8 @@
function f() {
uint x = 2;
x;
}
function g(uint[] storage x) pure { x[0] = 1; }
// ----
// Warning 2018: (0-39): Function state mutability can be restricted to pure
// TypeError 8961: (76-80): Function declared as pure, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
@@ -0,0 +1,9 @@
function f(uint) returns (bytes memory) {}
function f(uint[] memory x) returns (bytes memory) { return f(x[0]); }
function g(uint8) {}
function g(uint16) {}
function t() {
g(2);
}
// ----
// TypeError 4487: (176-177): No unique declaration found after argument-dependent lookup.
@@ -0,0 +1,4 @@
function fun() override {
}
// ----
// SyntaxError 1750: (0-27): Free functions cannot override.
@@ -0,0 +1,4 @@
function fun() payable {
}
// ----
// TypeError 9559: (0-26): Free functions cannot be payable.
@@ -0,0 +1,3 @@
receive() {}
// ----
// ParserError 7858: (0-7): Expected pragma, import directive or contract/interface/library/struct/enum/function definition.
@@ -0,0 +1,4 @@
struct S { uint x; }
function fun(S storage) {
}
// ----
@@ -0,0 +1,4 @@
function fun() virtual {
}
// ----
// SyntaxError 4493: (0-26): Free functions cannot be virtual.
@@ -0,0 +1,4 @@
contract C {}
function C() {}
// ----
// DeclarationError 2333: (14-29): Identifier already declared.
@@ -0,0 +1,6 @@
contract C {
struct S { uint x; }
}
function f() returns (uint) { S storage t; }
// ----
// DeclarationError 7920: (70-71): Identifier not found or not unique.
@@ -0,0 +1,6 @@
function fun() {
fun{gas: 1}();
fun{value: 1}();
}
// ----
// TypeError 2193: (21-32): Function call options can only be set on external function calls or contract creations.
@@ -0,0 +1,7 @@
function f() returns (uint) { C.S storage t; t.x; }
contract C {
struct S { uint x; }
}
// ----
// TypeError 3464: (45-46): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,3 @@
function f(S storage g) view returns (uint) { S storage t = g; return t.x; }
struct S { uint x; }
// ----
@@ -0,0 +1,6 @@
contract C {}
function f() {
super;
}
// ----
// DeclarationError 7576: (33-38): Undeclared identifier. "super" is not (or not yet) visible at this point.
@@ -0,0 +1,6 @@
contract C {}
function f() {
this;
}
// ----
// DeclarationError 7576: (33-37): Undeclared identifier. "this" is not (or not yet) visible at this point.
@@ -0,0 +1,14 @@
==== Source: a ====
function f(uint x) pure returns (uint) { return x * 3; }
==== Source: b ====
import "a" as A;
function g(uint x) pure returns (uint) { return A.f(x) * 3; }
==== Source: c ====
import "b" as B;
contract C {
function f() public pure {
B.g(2);
B.A.f(3);
}
}
// ----