aboutsummaryrefslogtreecommitdiffstats
path: root/test/libsolidity/ViewPureChecker.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-11-14 02:33:35 +0800
committerGitHub <noreply@github.com>2018-11-14 02:33:35 +0800
commit1d4f565a64988a3400847d2655ca24f73f234bc6 (patch)
treecaaa6c26e307513505349b50ca4f2a8a9506752b /test/libsolidity/ViewPureChecker.cpp
parent59dbf8f1085b8b92e8b7eb0ce380cbeb642e97eb (diff)
parent91b6b8a88e76016e0324036cb7a7f9300a1e2439 (diff)
downloaddexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.gz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.bz2
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.lz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.xz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.zst
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.zip
Merge pull request #5416 from ethereum/develop
Merge develop into release for 0.5.0
Diffstat (limited to 'test/libsolidity/ViewPureChecker.cpp')
-rw-r--r--test/libsolidity/ViewPureChecker.cpp372
1 files changed, 15 insertions, 357 deletions
diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp
index cd0a0b01..b7ea1efc 100644
--- a/test/libsolidity/ViewPureChecker.cpp
+++ b/test/libsolidity/ViewPureChecker.cpp
@@ -38,91 +38,27 @@ namespace test
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)
{
vector<string> view{
"block.coinbase",
"block.timestamp",
- "block.blockhash(7)",
"block.difficulty",
"block.number",
"block.gaslimit",
"blockhash(7)",
"gasleft()",
- "msg.gas",
"msg.value",
"msg.sender",
"tx.origin",
"tx.gasprice",
"this",
- "address(1).balance"
+ "address(1).balance",
};
- // ``block.blockhash`` and ``blockhash`` are tested seperately below because their usage will
+ if (dev::test::Options::get().evmVersion().hasStaticCall())
+ view.emplace_back("address(0x4242).staticcall(\"\")");
+
+ // ``block.blockhash`` and ``blockhash`` are tested separately below because their usage will
// produce warnings that can't be handled in a generic way.
vector<string> pure{
"msg.data",
@@ -155,282 +91,29 @@ BOOST_AUTO_TEST_CASE(environment_access)
"Statement has no effect."
}));
- CHECK_WARNING_ALLOW_MULTI(
- "contract C { function f() view public { block.blockhash; } }",
- (std::vector<std::string>{
- "Function state mutability can be restricted to pure",
- "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""
- }));
-}
-
-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; } }",
+ "contract C { function f() view public { block.blockhash; } }",
TypeError,
- "Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable."
+ "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""
);
-
-}
-
-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)
+BOOST_AUTO_TEST_CASE(address_staticcall)
{
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;
+ function i() view public returns (bool) {
+ (bool success,) = address(0x4242).staticcall("");
+ return success;
}
}
)";
- 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);
+ if (!dev::test::Options::get().evmVersion().hasStaticCall())
+ CHECK_ERROR(text, TypeError, "\"staticcall\" is not supported by the VM version.");
+ else
+ 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)
{
@@ -447,31 +130,6 @@ BOOST_AUTO_TEST_CASE(assembly_staticcall)
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()
}