diff options
Diffstat (limited to 'test')
17 files changed, 404 insertions, 7 deletions
diff --git a/test/libdevcore/UTF8.cpp b/test/libdevcore/UTF8.cpp index 6de4570f..daf47bb0 100644 --- a/test/libdevcore/UTF8.cpp +++ b/test/libdevcore/UTF8.cpp @@ -148,7 +148,7 @@ hélló Ḕ ḕ Ḗ ḗ Ḙ ḙ Ḛ -ἐ ἑ ἒ ἓ ἔ ἕ +ἐ ἑ ἒ ἓ ἔ ἕ ₠ ₡ ₢ ₣ ₤ ₥ @@ -164,9 +164,9 @@ hélló ␀ ␁ ␂ ␃ ␄ ␅ -⑀ ⑁ ⑂ ⑃ ⑄ +⑀ ⑁ ⑂ ⑃ ⑄ -① ② ③ ④ ⑤ +① ② ③ ④ ⑤ ╘ ╙ ╚ ╛ ╜ ╝ @@ -200,7 +200,7 @@ hélló שּׁ שּׂ אַ אָ אּ -ﮄ ﮅ ﮆ ﮇ ﮈ ﮉ +ﮄ ﮅ ﮆ ﮇ ﮈ ﮉ ﺵ ﺶ ﺷ ﺸ diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 8a334e5e..2bf20126 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -3592,6 +3592,19 @@ BOOST_AUTO_TEST_CASE(default_fallback_throws) )YY"; compileAndRun(sourceCode); ABI_CHECK(callContractFunction("f()"), encodeArgs(0)); + + if (dev::test::Options::get().evmVersion().hasStaticCall()) + { + char const* sourceCode = R"YY( + contract A { + function f() public returns (bool) { + return address(this).staticcall(""); + } + } + )YY"; + compileAndRun(sourceCode); + ABI_CHECK(callContractFunction("f()"), encodeArgs(0)); + } } BOOST_AUTO_TEST_CASE(short_data_calls_fallback) @@ -3937,6 +3950,209 @@ BOOST_AUTO_TEST_CASE(event_really_really_lots_of_data_from_storage) BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)"))); } +BOOST_AUTO_TEST_CASE(event_struct_memory_v2) +{ + char const* sourceCode = R"( + pragma experimental ABIEncoderV2; + contract C { + struct S { uint a; } + event E(S); + function createEvent(uint x) public { + emit E(S(x)); + } + } + )"; + compileAndRun(sourceCode); + u256 x(42); + callContractFunction("createEvent(uint256)", x); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data == encodeArgs(x)); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E((uint256))"))); +} + +BOOST_AUTO_TEST_CASE(event_struct_storage_v2) +{ + char const* sourceCode = R"( + pragma experimental ABIEncoderV2; + contract C { + struct S { uint a; } + event E(S); + S s; + function createEvent(uint x) public { + s.a = x; + emit E(s); + } + } + )"; + compileAndRun(sourceCode); + u256 x(42); + callContractFunction("createEvent(uint256)", x); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data == encodeArgs(x)); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E((uint256))"))); +} + +BOOST_AUTO_TEST_CASE(event_dynamic_array_memory) +{ + char const* sourceCode = R"( + contract C { + event E(uint[]); + function createEvent(uint x) public { + uint[] memory arr = new uint[](3); + arr[0] = x; + arr[1] = x + 1; + arr[2] = x + 2; + emit E(arr); + } + } + )"; + compileAndRun(sourceCode); + u256 x(42); + callContractFunction("createEvent(uint256)", x); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2)); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])"))); +} + +BOOST_AUTO_TEST_CASE(event_dynamic_array_memory_v2) +{ + char const* sourceCode = R"( + pragma experimental ABIEncoderV2; + contract C { + event E(uint[]); + function createEvent(uint x) public { + uint[] memory arr = new uint[](3); + arr[0] = x; + arr[1] = x + 1; + arr[2] = x + 2; + emit E(arr); + } + } + )"; + compileAndRun(sourceCode); + u256 x(42); + callContractFunction("createEvent(uint256)", x); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2)); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])"))); +} + +BOOST_AUTO_TEST_CASE(event_dynamic_nested_array_memory_v2) +{ + char const* sourceCode = R"( + pragma experimental ABIEncoderV2; + contract C { + event E(uint[][]); + function createEvent(uint x) public { + uint[][] memory arr = new uint[][](2); + arr[0] = new uint[](2); + arr[1] = new uint[](2); + arr[0][0] = x; + arr[0][1] = x + 1; + arr[1][0] = x + 2; + arr[1][1] = x + 3; + emit E(arr); + } + } + )"; + compileAndRun(sourceCode); + u256 x(42); + callContractFunction("createEvent(uint256)", x); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 2, 0x40, 0xa0, 2, x, x + 1, 2, x + 2, x + 3)); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[][])"))); +} + +BOOST_AUTO_TEST_CASE(event_dynamic_array_storage) +{ + char const* sourceCode = R"( + contract C { + event E(uint[]); + uint[] arr; + function createEvent(uint x) public { + arr.length = 3; + arr[0] = x; + arr[1] = x + 1; + arr[2] = x + 2; + emit E(arr); + } + } + )"; + compileAndRun(sourceCode); + u256 x(42); + callContractFunction("createEvent(uint256)", x); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2)); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])"))); +} + +BOOST_AUTO_TEST_CASE(event_dynamic_array_storage_v2) +{ + char const* sourceCode = R"( + pragma experimental ABIEncoderV2; + contract C { + event E(uint[]); + uint[] arr; + function createEvent(uint x) public { + arr.length = 3; + arr[0] = x; + arr[1] = x + 1; + arr[2] = x + 2; + emit E(arr); + } + } + )"; + compileAndRun(sourceCode); + u256 x(42); + callContractFunction("createEvent(uint256)", x); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2)); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])"))); +} + +BOOST_AUTO_TEST_CASE(event_dynamic_nested_array_storage_v2) +{ + char const* sourceCode = R"( + pragma experimental ABIEncoderV2; + contract C { + event E(uint[][]); + uint[][] arr; + function createEvent(uint x) public { + arr.length = 2; + arr[0].length = 2; + arr[1].length = 2; + arr[0][0] = x; + arr[0][1] = x + 1; + arr[1][0] = x + 2; + arr[1][1] = x + 3; + emit E(arr); + } + } + )"; + compileAndRun(sourceCode); + u256 x(42); + callContractFunction("createEvent(uint256)", x); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 2, 0x40, 0xa0, 2, x, x + 1, 2, x + 2, x + 3)); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[][])"))); +} + BOOST_AUTO_TEST_CASE(event_indexed_string) { char const* sourceCode = R"( @@ -4215,6 +4431,49 @@ BOOST_AUTO_TEST_CASE(generic_delegatecall) BOOST_CHECK_EQUAL(balanceAt(c_senderAddress), 50 + 11); } +BOOST_AUTO_TEST_CASE(generic_staticcall) +{ + if (dev::test::Options::get().evmVersion().hasStaticCall()) + { + char const* sourceCode = R"**( + contract A { + uint public x; + constructor() public { x = 42; } + function pureFunction(uint256 p) public pure returns (uint256) { return p; } + function viewFunction(uint256 p) public view returns (uint256) { return p + x; } + function nonpayableFunction(uint256 p) public returns (uint256) { x = p; return x; } + function assertFunction(uint256 p) public view returns (uint256) { assert(x == p); return x; } + } + contract C { + function f(address a) public view returns (bool) + { + return a.staticcall(abi.encodeWithSignature("pureFunction(uint256)", 23)); + } + function g(address a) public view returns (bool) + { + return a.staticcall(abi.encodeWithSignature("viewFunction(uint256)", 23)); + } + function h(address a) public view returns (bool) + { + return a.staticcall(abi.encodeWithSignature("nonpayableFunction(uint256)", 23)); + } + function i(address a, uint256 v) public view returns (bool) + { + return a.staticcall(abi.encodeWithSignature("assertFunction(uint256)", v)); + } + } + )**"; + compileAndRun(sourceCode, 0, "A"); + u160 const c_addressA = m_contractAddress; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f(address)", c_addressA), encodeArgs(true)); + ABI_CHECK(callContractFunction("g(address)", c_addressA), encodeArgs(true)); + ABI_CHECK(callContractFunction("h(address)", c_addressA), encodeArgs(false)); + ABI_CHECK(callContractFunction("i(address,uint256)", c_addressA, 42), encodeArgs(true)); + ABI_CHECK(callContractFunction("i(address,uint256)", c_addressA, 23), encodeArgs(false)); + } +} + BOOST_AUTO_TEST_CASE(library_call_in_homestead) { char const* sourceCode = R"( @@ -12216,6 +12475,19 @@ BOOST_AUTO_TEST_CASE(bare_call_invalid_address) compileAndRun(sourceCode, 0, "C"); ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1))); ABI_CHECK(callContractFunction("h()"), encodeArgs(u256(1))); + + if (dev::test::Options::get().evmVersion().hasStaticCall()) + { + char const* sourceCode = R"YY( + contract C { + function f() external returns (bool) { + return address(0x4242).staticcall(""); + } + } + )YY"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1))); + } } BOOST_AUTO_TEST_CASE(delegatecall_return_value) diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 55e81867..387505a5 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -433,6 +433,37 @@ BOOST_AUTO_TEST_CASE(getter_is_memory_type) } } +BOOST_AUTO_TEST_CASE(address_staticcall) +{ + char const* sourceCode = R"( + contract C { + function f() public view returns(bool) { + return address(0x4242).staticcall(""); + } + } + )"; + + if (dev::test::Options::get().evmVersion().hasStaticCall()) + CHECK_SUCCESS_NO_WARNINGS(sourceCode); + else + CHECK_ERROR(sourceCode, TypeError, "\"staticcall\" is not supported by the VM version."); +} + +BOOST_AUTO_TEST_CASE(address_staticcall_value) +{ + if (dev::test::Options::get().evmVersion().hasStaticCall()) + { + char const* sourceCode = R"( + contract C { + function f() public view { + address(0x4242).staticcall.value; + } + } + )"; + CHECK_ERROR(sourceCode, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup"); + } +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp index b97df972..d77050cb 100644 --- a/test/libsolidity/SolidityNatspecJSON.cpp +++ b/test/libsolidity/SolidityNatspecJSON.cpp @@ -647,7 +647,7 @@ BOOST_AUTO_TEST_CASE(dev_documenting_no_paramname) contract test { /// @dev Multiplies a number by 7 and adds second parameter /// @param a Documentation for the first parameter - /// @param + /// @param function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } } )"; @@ -675,7 +675,7 @@ BOOST_AUTO_TEST_CASE(dev_documenting_no_param_description) contract test { /// @dev Multiplies a number by 7 and adds second parameter /// @param a Documentation for the first parameter - /// @param second + /// @param second function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } } )"; diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp index 299cd084..d993b92e 100644 --- a/test/libsolidity/ViewPureChecker.cpp +++ b/test/libsolidity/ViewPureChecker.cpp @@ -53,8 +53,11 @@ BOOST_AUTO_TEST_CASE(environment_access) "tx.origin", "tx.gasprice", "this", - "address(1).balance" + "address(1).balance", }; + 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{ @@ -95,6 +98,22 @@ BOOST_AUTO_TEST_CASE(environment_access) ); } +BOOST_AUTO_TEST_CASE(address_staticcall) +{ + string text = R"( + contract C { + function i() view public returns (bool) { + return address(0x4242).staticcall(""); + } + } + )"; + 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_staticcall) { string text = R"( diff --git a/test/libsolidity/syntaxTests/events/event_array_indexed_v2.sol b/test/libsolidity/syntaxTests/events/event_array_indexed_v2.sol new file mode 100644 index 00000000..aaf6028a --- /dev/null +++ b/test/libsolidity/syntaxTests/events/event_array_indexed_v2.sol @@ -0,0 +1,7 @@ +pragma experimental ABIEncoderV2; +contract c { + event E(uint[] indexed); +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError: (59-65): Indexed reference types cannot yet be used with ABIEncoderV2. diff --git a/test/libsolidity/syntaxTests/events/event_array_v2.sol b/test/libsolidity/syntaxTests/events/event_array_v2.sol new file mode 100644 index 00000000..9ccd9fc9 --- /dev/null +++ b/test/libsolidity/syntaxTests/events/event_array_v2.sol @@ -0,0 +1,6 @@ +pragma experimental ABIEncoderV2; +contract c { + event E(uint[]); +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/events/event_nested_array_indexed_v2.sol b/test/libsolidity/syntaxTests/events/event_nested_array_indexed_v2.sol new file mode 100644 index 00000000..ffae5b9c --- /dev/null +++ b/test/libsolidity/syntaxTests/events/event_nested_array_indexed_v2.sol @@ -0,0 +1,7 @@ +pragma experimental ABIEncoderV2; +contract c { + event E(uint[][] indexed); +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError: (59-67): Indexed reference types cannot yet be used with ABIEncoderV2. diff --git a/test/libsolidity/syntaxTests/events/event_nested_array_v2.sol b/test/libsolidity/syntaxTests/events/event_nested_array_v2.sol new file mode 100644 index 00000000..efc7439e --- /dev/null +++ b/test/libsolidity/syntaxTests/events/event_nested_array_v2.sol @@ -0,0 +1,6 @@ +pragma experimental ABIEncoderV2; +contract c { + event E(uint[][]); +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/events/event_struct_indexed_v2.sol b/test/libsolidity/syntaxTests/events/event_struct_indexed_v2.sol new file mode 100644 index 00000000..a8e0837f --- /dev/null +++ b/test/libsolidity/syntaxTests/events/event_struct_indexed_v2.sol @@ -0,0 +1,8 @@ +pragma experimental ABIEncoderV2; +contract c { + struct S { uint a ; } + event E(S indexed); +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError: (85-86): Indexed reference types cannot yet be used with ABIEncoderV2. diff --git a/test/libsolidity/syntaxTests/events/event_struct_v2.sol b/test/libsolidity/syntaxTests/events/event_struct_v2.sol new file mode 100644 index 00000000..97ca61b6 --- /dev/null +++ b/test/libsolidity/syntaxTests/events/event_struct_v2.sol @@ -0,0 +1,7 @@ +pragma experimental ABIEncoderV2; +contract c { + struct S { uint a ; } + event E(S); +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_1.sol b/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_1.sol new file mode 100644 index 00000000..ea2d282c --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_1.sol @@ -0,0 +1,5 @@ +contract c { + mapping(uint[] => uint) data; +} +// ---- +// ParserError: (26-27): Expected '=>' but got '[' diff --git a/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_2.sol b/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_2.sol new file mode 100644 index 00000000..713cddeb --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_2.sol @@ -0,0 +1,8 @@ +contract c { + struct S { + uint x; + } + mapping(S => uint) data; +} +// ---- +// ParserError: (47-48): Expected elementary type name for mapping key type diff --git a/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_3.sol b/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_3.sol new file mode 100644 index 00000000..655af9de --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_3.sol @@ -0,0 +1,8 @@ +contract c { + struct S { + string s; + } + mapping(S => uint) data; +} +// ---- +// ParserError: (49-50): Expected elementary type name for mapping key type diff --git a/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_4.sol b/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_4.sol new file mode 100644 index 00000000..f4dcb00a --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_4.sol @@ -0,0 +1,5 @@ +contract c { + mapping(string[] => uint) data; +} +// ---- +// ParserError: (28-29): Expected '=>' but got '[' diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_dynamic_key.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_dynamic_key.sol new file mode 100644 index 00000000..825ee09a --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_dynamic_key.sol @@ -0,0 +1,3 @@ +contract c { + mapping(string => uint) data; +} diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_dynamic_key_public.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_dynamic_key_public.sol new file mode 100644 index 00000000..9fb575af --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_dynamic_key_public.sol @@ -0,0 +1,5 @@ +contract c { + mapping(string => uint) public data; +} +// ---- +// TypeError: (14-49): Dynamically-sized keys for public mappings are not supported. |