mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #4222 from ethereum/view-pure-checker-split
Extract test cases from ViewPureChecker
This commit is contained in:
commit
d97aca77f2
@ -38,71 +38,6 @@ namespace test
|
|||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(ViewPureChecker, AnalysisFramework)
|
BOOST_FIXTURE_TEST_SUITE(ViewPureChecker, AnalysisFramework)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(smoke_test)
|
|
||||||
{
|
|
||||||
char const* text = R"(
|
|
||||||
contract C {
|
|
||||||
uint x;
|
|
||||||
function g() pure public {}
|
|
||||||
function f() view public returns (uint) { return now; }
|
|
||||||
function h() public { x = 2; }
|
|
||||||
function i() payable public { x = 2; }
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(call_internal_functions_success)
|
|
||||||
{
|
|
||||||
char const* text = R"(
|
|
||||||
contract C {
|
|
||||||
function g() pure public { g(); }
|
|
||||||
function f() view public returns (uint) { f(); g(); }
|
|
||||||
function h() public { h(); g(); f(); }
|
|
||||||
function i() payable public { i(); h(); g(); f(); }
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(suggest_pure)
|
|
||||||
{
|
|
||||||
char const* text = R"(
|
|
||||||
contract C {
|
|
||||||
function g() view public { }
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_WARNING(text, "can be restricted to pure");
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(suggest_view)
|
|
||||||
{
|
|
||||||
char const* text = R"(
|
|
||||||
contract C {
|
|
||||||
uint x;
|
|
||||||
function g() public returns (uint) { return x; }
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_WARNING(text, "can be restricted to view");
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(call_internal_functions_fail)
|
|
||||||
{
|
|
||||||
CHECK_ERROR(
|
|
||||||
"contract C{ function f() pure public { g(); } function g() view public {} }",
|
|
||||||
TypeError,
|
|
||||||
"Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires \"view\""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(write_storage_fail)
|
|
||||||
{
|
|
||||||
CHECK_WARNING(
|
|
||||||
"contract C{ uint x; function f() view public { x = 2; } }",
|
|
||||||
"Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(environment_access)
|
BOOST_AUTO_TEST_CASE(environment_access)
|
||||||
{
|
{
|
||||||
vector<string> view{
|
vector<string> view{
|
||||||
@ -163,275 +98,6 @@ BOOST_AUTO_TEST_CASE(environment_access)
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(view_error_for_050)
|
|
||||||
{
|
|
||||||
CHECK_ERROR(
|
|
||||||
"pragma experimental \"v0.5.0\"; contract C { uint x; function f() view public { x = 2; } }",
|
|
||||||
TypeError,
|
|
||||||
"Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable."
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(modifiers)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract D {
|
|
||||||
uint x;
|
|
||||||
modifier purem(uint) { _; }
|
|
||||||
modifier viewm(uint) { uint a = x; _; a; }
|
|
||||||
modifier nonpayablem(uint) { x = 2; _; }
|
|
||||||
}
|
|
||||||
contract C is D {
|
|
||||||
function f() purem(0) pure public {}
|
|
||||||
function g() viewm(0) view public {}
|
|
||||||
function h() nonpayablem(0) public {}
|
|
||||||
function i() purem(x) view public {}
|
|
||||||
function j() viewm(x) view public {}
|
|
||||||
function k() nonpayablem(x) public {}
|
|
||||||
function l() purem(x = 2) public {}
|
|
||||||
function m() viewm(x = 2) public {}
|
|
||||||
function n() nonpayablem(x = 2) public {}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(interface)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
interface D {
|
|
||||||
function f() view external;
|
|
||||||
}
|
|
||||||
contract C is D {
|
|
||||||
function f() view external {}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(overriding)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract D {
|
|
||||||
uint x;
|
|
||||||
function f() public { x = 2; }
|
|
||||||
}
|
|
||||||
contract C is D {
|
|
||||||
function f() public {}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(returning_structs)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
struct S { uint x; }
|
|
||||||
S s;
|
|
||||||
function f() view internal returns (S storage) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
function g() public {
|
|
||||||
f().x = 2;
|
|
||||||
}
|
|
||||||
function h() view public {
|
|
||||||
f();
|
|
||||||
f().x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(mappings)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
mapping(uint => uint) a;
|
|
||||||
function f() view public {
|
|
||||||
a;
|
|
||||||
}
|
|
||||||
function g() view public {
|
|
||||||
a[2];
|
|
||||||
}
|
|
||||||
function h() public {
|
|
||||||
a[2] = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(local_storage_variables)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
struct S { uint a; }
|
|
||||||
S s;
|
|
||||||
function f() view public {
|
|
||||||
S storage x = s;
|
|
||||||
x;
|
|
||||||
}
|
|
||||||
function g() view public {
|
|
||||||
S storage x = s;
|
|
||||||
x = s;
|
|
||||||
}
|
|
||||||
function i() public {
|
|
||||||
s.a = 2;
|
|
||||||
}
|
|
||||||
function h() public {
|
|
||||||
S storage x = s;
|
|
||||||
x.a = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(builtin_functions)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
function f() public {
|
|
||||||
address(this).transfer(1);
|
|
||||||
require(address(this).send(2));
|
|
||||||
selfdestruct(address(this));
|
|
||||||
require(address(this).delegatecall());
|
|
||||||
require(address(this).call());
|
|
||||||
}
|
|
||||||
function g() pure public {
|
|
||||||
bytes32 x = keccak256("abc");
|
|
||||||
bytes32 y = sha256("abc");
|
|
||||||
address z = ecrecover(1, 2, 3, 4);
|
|
||||||
require(true);
|
|
||||||
assert(true);
|
|
||||||
x; y; z;
|
|
||||||
}
|
|
||||||
function() payable public {}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_types)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
function f() pure public {
|
|
||||||
function () external nonpayFun;
|
|
||||||
function () external view viewFun;
|
|
||||||
function () external pure pureFun;
|
|
||||||
|
|
||||||
nonpayFun;
|
|
||||||
viewFun;
|
|
||||||
pureFun;
|
|
||||||
pureFun();
|
|
||||||
}
|
|
||||||
function g() view public {
|
|
||||||
function () external view viewFun;
|
|
||||||
|
|
||||||
viewFun();
|
|
||||||
}
|
|
||||||
function h() public {
|
|
||||||
function () external nonpayFun;
|
|
||||||
|
|
||||||
nonpayFun();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(selector)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
uint public x;
|
|
||||||
function f() payable public {
|
|
||||||
}
|
|
||||||
function g() pure public returns (bytes4) {
|
|
||||||
return this.f.selector ^ this.x.selector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(selector_complex)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
function f(C c) pure public returns (C) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
function g() pure public returns (bytes4) {
|
|
||||||
// By passing `this`, we read from the state, even if f itself is pure.
|
|
||||||
return f(this).f.selector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_ERROR(text, TypeError, "reads from the environment or state and thus requires \"view\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(selector_complex2)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
function f() payable public returns (C) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
function g() pure public returns (bytes4) {
|
|
||||||
C x = C(0x123);
|
|
||||||
return x.f.selector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(creation)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract D {}
|
|
||||||
contract C {
|
|
||||||
function f() public { new D(); }
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assembly)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
struct S { uint x; }
|
|
||||||
S s;
|
|
||||||
function e() pure public {
|
|
||||||
assembly { mstore(keccak256(0, 20), mul(s_slot, 2)) }
|
|
||||||
}
|
|
||||||
function f() pure public {
|
|
||||||
uint x;
|
|
||||||
assembly { x := 7 }
|
|
||||||
}
|
|
||||||
function g() view public {
|
|
||||||
assembly { for {} 1 { pop(sload(0)) } { } pop(gas) }
|
|
||||||
}
|
|
||||||
function h() view public {
|
|
||||||
assembly { function g() { pop(blockhash(20)) } }
|
|
||||||
}
|
|
||||||
function j() public {
|
|
||||||
assembly { pop(call(0, 1, 2, 3, 4, 5, 6)) }
|
|
||||||
}
|
|
||||||
function k() public {
|
|
||||||
assembly { pop(call(gas, 1, 2, 3, 4, 5, 6)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assembly_staticcall)
|
BOOST_AUTO_TEST_CASE(assembly_staticcall)
|
||||||
{
|
{
|
||||||
string text = R"(
|
string text = R"(
|
||||||
@ -447,31 +113,6 @@ BOOST_AUTO_TEST_CASE(assembly_staticcall)
|
|||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
CHECK_SUCCESS_NO_WARNINGS(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assembly_jump)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
function k() public {
|
|
||||||
assembly { jump(2) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_WARNING(text, "low-level EVM features");
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(constant)
|
|
||||||
{
|
|
||||||
string text = R"(
|
|
||||||
contract C {
|
|
||||||
uint constant x = 2;
|
|
||||||
function k() pure public returns (uint) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
23
test/libsolidity/syntaxTests/viewPureChecker/assembly.sol
Normal file
23
test/libsolidity/syntaxTests/viewPureChecker/assembly.sol
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
contract C {
|
||||||
|
struct S { uint x; }
|
||||||
|
S s;
|
||||||
|
function e() pure public {
|
||||||
|
assembly { mstore(keccak256(0, 20), mul(s_slot, 2)) }
|
||||||
|
}
|
||||||
|
function f() pure public {
|
||||||
|
uint x;
|
||||||
|
assembly { x := 7 }
|
||||||
|
}
|
||||||
|
function g() view public {
|
||||||
|
assembly { for {} 1 { pop(sload(0)) } { } pop(gas) }
|
||||||
|
}
|
||||||
|
function h() view public {
|
||||||
|
assembly { function g() { pop(blockhash(20)) } }
|
||||||
|
}
|
||||||
|
function j() public {
|
||||||
|
assembly { pop(call(0, 1, 2, 3, 4, 5, 6)) }
|
||||||
|
}
|
||||||
|
function k() public {
|
||||||
|
assembly { pop(call(gas, 1, 2, 3, 4, 5, 6)) }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
contract C {
|
||||||
|
function k() public {
|
||||||
|
assembly { jump(2) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// Warning: (58-65): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are discouraged. Please consider using "switch", "if" or "for" statements instead.
|
@ -0,0 +1,18 @@
|
|||||||
|
contract C {
|
||||||
|
function f() public {
|
||||||
|
address(this).transfer(1);
|
||||||
|
require(address(this).send(2));
|
||||||
|
selfdestruct(address(this));
|
||||||
|
require(address(this).delegatecall());
|
||||||
|
require(address(this).call());
|
||||||
|
}
|
||||||
|
function g() pure public {
|
||||||
|
bytes32 x = keccak256("abc");
|
||||||
|
bytes32 y = sha256("abc");
|
||||||
|
address z = ecrecover(1, 2, 3, 4);
|
||||||
|
require(true);
|
||||||
|
assert(true);
|
||||||
|
x; y; z;
|
||||||
|
}
|
||||||
|
function() payable public {}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
contract C {
|
||||||
|
function f() pure public { g(); }
|
||||||
|
function g() view public {}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError: (44-47): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".
|
||||||
|
// Warning: (55-82): Function state mutability can be restricted to pure
|
@ -0,0 +1,6 @@
|
|||||||
|
contract C {
|
||||||
|
function g() pure public { g(); }
|
||||||
|
function f() view public returns (uint) { f(); g(); }
|
||||||
|
function h() public { h(); g(); f(); }
|
||||||
|
function i() payable public { i(); h(); g(); f(); }
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
contract C {
|
||||||
|
uint constant x = 2;
|
||||||
|
function k() pure public returns (uint) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
contract D {}
|
||||||
|
contract C {
|
||||||
|
function f() public { new D(); }
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
contract C {
|
||||||
|
function f() pure public {
|
||||||
|
function () external nonpayFun;
|
||||||
|
function () external view viewFun;
|
||||||
|
function () external pure pureFun;
|
||||||
|
|
||||||
|
nonpayFun;
|
||||||
|
viewFun;
|
||||||
|
pureFun;
|
||||||
|
pureFun();
|
||||||
|
}
|
||||||
|
function g() view public {
|
||||||
|
function () external view viewFun;
|
||||||
|
|
||||||
|
viewFun();
|
||||||
|
}
|
||||||
|
function h() public {
|
||||||
|
function () external nonpayFun;
|
||||||
|
|
||||||
|
nonpayFun();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
interface D {
|
||||||
|
function f() view external;
|
||||||
|
}
|
||||||
|
contract C is D {
|
||||||
|
function f() view external {}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
contract C {
|
||||||
|
struct S { uint a; }
|
||||||
|
S s;
|
||||||
|
function f() view public {
|
||||||
|
S storage x = s;
|
||||||
|
x;
|
||||||
|
}
|
||||||
|
function g() view public {
|
||||||
|
S storage x = s;
|
||||||
|
x = s;
|
||||||
|
}
|
||||||
|
function i() public {
|
||||||
|
s.a = 2;
|
||||||
|
}
|
||||||
|
function h() public {
|
||||||
|
S storage x = s;
|
||||||
|
x.a = 2;
|
||||||
|
}
|
||||||
|
}
|
12
test/libsolidity/syntaxTests/viewPureChecker/mappings.sol
Normal file
12
test/libsolidity/syntaxTests/viewPureChecker/mappings.sol
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
contract C {
|
||||||
|
mapping(uint => uint) a;
|
||||||
|
function f() view public {
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
function g() view public {
|
||||||
|
a[2];
|
||||||
|
}
|
||||||
|
function h() public {
|
||||||
|
a[2] = 3;
|
||||||
|
}
|
||||||
|
}
|
17
test/libsolidity/syntaxTests/viewPureChecker/modifiers.sol
Normal file
17
test/libsolidity/syntaxTests/viewPureChecker/modifiers.sol
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
contract D {
|
||||||
|
uint x;
|
||||||
|
modifier purem(uint) { _; }
|
||||||
|
modifier viewm(uint) { uint a = x; _; a; }
|
||||||
|
modifier nonpayablem(uint) { x = 2; _; }
|
||||||
|
}
|
||||||
|
contract C is D {
|
||||||
|
function f() purem(0) pure public {}
|
||||||
|
function g() viewm(0) view public {}
|
||||||
|
function h() nonpayablem(0) public {}
|
||||||
|
function i() purem(x) view public {}
|
||||||
|
function j() viewm(x) view public {}
|
||||||
|
function k() nonpayablem(x) public {}
|
||||||
|
function l() purem(x = 2) public {}
|
||||||
|
function m() viewm(x = 2) public {}
|
||||||
|
function n() nonpayablem(x = 2) public {}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
contract D {
|
||||||
|
uint x;
|
||||||
|
function f() public { x = 2; }
|
||||||
|
}
|
||||||
|
contract C is D {
|
||||||
|
function f() public {}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
contract C {
|
||||||
|
struct S { uint x; }
|
||||||
|
S s;
|
||||||
|
function f() view internal returns (S storage) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
function g() public {
|
||||||
|
f().x = 2;
|
||||||
|
}
|
||||||
|
function h() view public {
|
||||||
|
f();
|
||||||
|
f().x;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
contract C {
|
||||||
|
uint public x;
|
||||||
|
function f() payable public {
|
||||||
|
}
|
||||||
|
function g() pure public returns (bytes4) {
|
||||||
|
return this.f.selector ^ this.x.selector;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
contract C {
|
||||||
|
function f(C c) pure public returns (C) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
function g() pure public returns (bytes4) {
|
||||||
|
// By passing `this`, we read from the state, even if f itself is pure.
|
||||||
|
return f(this).f.selector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError: (228-232): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".
|
@ -0,0 +1,9 @@
|
|||||||
|
contract C {
|
||||||
|
function f() payable public returns (C) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
function g() pure public returns (bytes4) {
|
||||||
|
C x = C(0x123);
|
||||||
|
return x.f.selector;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
contract C {
|
||||||
|
uint x;
|
||||||
|
function g() pure public {}
|
||||||
|
function f() view public returns (uint) { return now; }
|
||||||
|
function h() public { x = 2; }
|
||||||
|
function i() payable public { x = 2; }
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
contract C {
|
||||||
|
function g() view public { }
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// Warning: (17-45): Function state mutability can be restricted to pure
|
@ -0,0 +1,6 @@
|
|||||||
|
contract C {
|
||||||
|
uint x;
|
||||||
|
function g() public returns (uint) { return x; }
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// Warning: (29-77): Function state mutability can be restricted to view
|
@ -0,0 +1,6 @@
|
|||||||
|
contract C {
|
||||||
|
uint x;
|
||||||
|
function f() view public { x = 2; }
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// Warning: (56-57): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
|
@ -0,0 +1,7 @@
|
|||||||
|
pragma experimental "v0.5.0";
|
||||||
|
contract C {
|
||||||
|
uint x;
|
||||||
|
function f() view public { x = 2; }
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError: (86-87): Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable.
|
Loading…
Reference in New Issue
Block a user