diff options
Diffstat (limited to 'test/libsolidity')
-rw-r--r-- | test/libsolidity/Assembly.cpp | 2 | ||||
-rw-r--r-- | test/libsolidity/SolidityABIJSON.cpp | 141 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 1033 | ||||
-rw-r--r-- | test/libsolidity/SolidityExecutionFramework.h | 3 | ||||
-rw-r--r-- | test/libsolidity/SolidityExpressionCompiler.cpp | 126 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 974 | ||||
-rw-r--r-- | test/libsolidity/SolidityNatspecJSON.cpp | 344 | ||||
-rw-r--r-- | test/libsolidity/SolidityOptimizer.cpp | 67 | ||||
-rw-r--r-- | test/libsolidity/SolidityParser.cpp | 734 |
9 files changed, 2013 insertions, 1411 deletions
diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index ed92ca2b..155dd5c9 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -75,7 +75,7 @@ eth::AssemblyItems compileContract(const string& _sourceCode) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) { Compiler compiler; - compiler.compileContract(*contract, map<ContractDefinition const*, Assembly const*>{}); + compiler.compileContract(*contract, map<ContractDefinition const*, Assembly const*>{}, bytes()); return compiler.runtimeAssemblyItems(); } diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp index 6fc2bcee..043d74ed 100644 --- a/test/libsolidity/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -22,8 +22,11 @@ #include "../TestHelper.h" #include <libsolidity/interface/CompilerStack.h> -#include <json/json.h> + #include <libdevcore/Exceptions.h> +#include <libdevcore/SwarmHash.h> + +#include <json/json.h> namespace dev { @@ -51,7 +54,7 @@ public: ); } -private: +protected: CompilerStack m_compilerStack; Json::Reader m_reader; }; @@ -60,9 +63,11 @@ BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, JSONInterfaceChecker) BOOST_AUTO_TEST_CASE(basic_test) { - char const* sourceCode = "contract test {\n" - " function f(uint a) returns(uint d) { return a * 7; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint d) { return a * 7; } + } + )"; char const* interface = R"([ { @@ -90,8 +95,9 @@ BOOST_AUTO_TEST_CASE(basic_test) BOOST_AUTO_TEST_CASE(empty_contract) { - char const* sourceCode = "contract test {\n" - "}\n"; + char const* sourceCode = R"( + contract test { } + )"; char const* interface = "[]"; checkInterface(sourceCode, interface); @@ -99,10 +105,12 @@ BOOST_AUTO_TEST_CASE(empty_contract) BOOST_AUTO_TEST_CASE(multiple_methods) { - char const* sourceCode = "contract test {\n" - " function f(uint a) returns(uint d) { return a * 7; }\n" - " function g(uint b) returns(uint e) { return b * 8; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint d) { return a * 7; } + function g(uint b) returns(uint e) { return b * 8; } + } + )"; char const* interface = R"([ { @@ -148,9 +156,11 @@ BOOST_AUTO_TEST_CASE(multiple_methods) BOOST_AUTO_TEST_CASE(multiple_params) { - char const* sourceCode = "contract test {\n" - " function f(uint a, uint b) returns(uint d) { return a + b; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a, uint b) returns(uint d) { return a + b; } + } + )"; char const* interface = R"([ { @@ -183,10 +193,12 @@ BOOST_AUTO_TEST_CASE(multiple_params) BOOST_AUTO_TEST_CASE(multiple_methods_order) { // methods are expected to be in alpabetical order - char const* sourceCode = "contract test {\n" - " function f(uint a) returns(uint d) { return a * 7; }\n" - " function c(uint b) returns(uint e) { return b * 8; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint d) { return a * 7; } + function c(uint b) returns(uint e) { return b * 8; } + } + )"; char const* interface = R"([ { @@ -232,10 +244,12 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order) BOOST_AUTO_TEST_CASE(const_function) { - char const* sourceCode = "contract test {\n" - " function foo(uint a, uint b) returns(uint d) { return a + b; }\n" - " function boo(uint32 a) constant returns(uint b) { return a * 4; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function foo(uint a, uint b) returns(uint d) { return a + b; } + function boo(uint32 a) constant returns(uint b) { return a * 4; } + } + )"; char const* interface = R"([ { @@ -283,11 +297,13 @@ BOOST_AUTO_TEST_CASE(const_function) BOOST_AUTO_TEST_CASE(events) { - char const* sourceCode = "contract test {\n" - " function f(uint a) returns(uint d) { return a * 7; }\n" - " event e1(uint b, address indexed c); \n" - " event e2(); \n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint d) { return a * 7; } + event e1(uint b, address indexed c); + event e2(); + } + )"; char const* interface = R"([ { "name": "f", @@ -338,9 +354,11 @@ BOOST_AUTO_TEST_CASE(events) BOOST_AUTO_TEST_CASE(events_anonymous) { - char const* sourceCode = "contract test {\n" - " event e() anonymous; \n" - "}\n"; + char const* sourceCode = R"( + contract test { + event e() anonymous; + } + )"; char const* interface = R"([ { "name": "e", @@ -356,15 +374,16 @@ BOOST_AUTO_TEST_CASE(events_anonymous) BOOST_AUTO_TEST_CASE(inherited) { - char const* sourceCode = - " contract Base { \n" - " function baseFunction(uint p) returns (uint i) { return p; } \n" - " event baseEvent(bytes32 indexed evtArgBase); \n" - " } \n" - " contract Derived is Base { \n" - " function derivedFunction(bytes32 p) returns (bytes32 i) { return p; } \n" - " event derivedEvent(uint indexed evtArgDerived); \n" - " }"; + char const* sourceCode = R"( + contract Base { + function baseFunction(uint p) returns (uint i) { return p; } + event baseEvent(bytes32 indexed evtArgBase); + } + contract Derived is Base { + function derivedFunction(bytes32 p) returns (bytes32 i) { return p; } + event derivedEvent(uint indexed evtArgDerived); + } + )"; char const* interface = R"([ { @@ -428,13 +447,14 @@ BOOST_AUTO_TEST_CASE(inherited) BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one) { char const* sourceCode = R"( - contract test { - function f(uint, uint k) returns(uint ret_k, uint ret_g){ - uint g = 8; - ret_k = k; - ret_g = g; + contract test { + function f(uint, uint k) returns(uint ret_k, uint ret_g) { + uint g = 8; + ret_k = k; + ret_g = g; + } } - })"; + )"; char const* interface = R"([ { @@ -472,10 +492,11 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter) { char const* sourceCode = R"( contract test { - function f(uint k) returns(uint){ - return k; + function f(uint k) returns(uint) { + return k; + } } - })"; + )"; char const* interface = R"([ { @@ -539,7 +560,7 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi) contract test { enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } function test(ActionChoices param) {} - function ret() returns(ActionChoices){ + function ret() returns(ActionChoices) { ActionChoices action = ActionChoices.GoLeft; return action; } @@ -609,7 +630,7 @@ BOOST_AUTO_TEST_CASE(library_function) char const* sourceCode = R"( library test { struct StructType { uint a; } - function f(StructType storage b, uint[] storage c, test d) returns (uint[] e, StructType storage f){} + function f(StructType storage b, uint[] storage c, test d) returns (uint[] e, StructType storage f) {} } )"; @@ -731,6 +752,26 @@ BOOST_AUTO_TEST_CASE(function_type) checkInterface(sourceCode, interface); } +BOOST_AUTO_TEST_CASE(metadata_stamp) +{ + // Check that the metadata stamp is at the end of the runtime bytecode. + char const* sourceCode = R"( + pragma solidity >=0.0; + contract test { + function g(function(uint) external returns (uint) x) {} + } + )"; + BOOST_REQUIRE(m_compilerStack.compile(std::string(sourceCode))); + bytes const& bytecode = m_compilerStack.runtimeObject("test").bytecode; + bytes hash = dev::swarmHash(m_compilerStack.onChainMetadata("test")).asBytes(); + BOOST_REQUIRE(hash.size() == 32); + BOOST_REQUIRE(bytecode.size() >= 2); + size_t metadataCBORSize = (size_t(bytecode.end()[-2]) << 8) + size_t(bytecode.end()[-1]); + BOOST_REQUIRE(metadataCBORSize < bytecode.size() - 2); + bytes expectation = bytes{0xa1, 0x65, 'b', 'z', 'z', 'r', '0', 0x58, 0x20} + hash; + BOOST_CHECK(std::equal(expectation.begin(), expectation.end(), bytecode.end() - metadataCBORSize - 2)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 62e9a457..2df6e9f2 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -44,17 +44,20 @@ BOOST_FIXTURE_TEST_SUITE(SolidityEndToEndTest, SolidityExecutionFramework) BOOST_AUTO_TEST_CASE(smoke_test) { - char const* sourceCode = "contract test {\n" - " function f(uint a) returns(uint d) { return a * 7; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint d) { return a * 7; } + } + )"; compileAndRun(sourceCode); testContractAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return a * 7; }, 0, 100); } BOOST_AUTO_TEST_CASE(empty_contract) { - char const* sourceCode = "contract test {\n" - "}\n"; + char const* sourceCode = R"( + contract test { } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("i_am_not_there()", bytes()).empty()); } @@ -64,7 +67,8 @@ BOOST_AUTO_TEST_CASE(exp_operator) char const* sourceCode = R"( contract test { function f(uint a) returns(uint d) { return 2 ** a; } - })"; + } + )"; compileAndRun(sourceCode); testContractAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return u256(1 << a.convert_to<int>()); }, 0, 16); } @@ -74,7 +78,8 @@ BOOST_AUTO_TEST_CASE(exp_operator_const) char const* sourceCode = R"( contract test { function f() returns(uint d) { return 2 ** 3; } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(8))); } @@ -84,7 +89,8 @@ BOOST_AUTO_TEST_CASE(exp_operator_const_signed) char const* sourceCode = R"( contract test { function f() returns(int d) { return (-2) ** 3; } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(-8))); } @@ -95,8 +101,9 @@ BOOST_AUTO_TEST_CASE(conditional_expression_true_literal) contract test { function f() returns(uint d) { return true ? 5 : 10; - } - })"; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(5))); } @@ -107,8 +114,9 @@ BOOST_AUTO_TEST_CASE(conditional_expression_false_literal) contract test { function f() returns(uint d) { return false ? 5 : 10; - } - })"; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(10))); } @@ -118,12 +126,13 @@ BOOST_AUTO_TEST_CASE(conditional_expression_multiple) char const* sourceCode = R"( contract test { function f(uint x) returns(uint d) { - return x > 100 ? + return x > 100 ? x > 1000 ? 1000 : 100 : x > 50 ? 50 : 10; - } - })"; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("f(uint256)", u256(1001)) == toBigEndian(u256(1000))); BOOST_CHECK(callContractFunction("f(uint256)", u256(500)) == toBigEndian(u256(100))); @@ -137,7 +146,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_return_values) contract test { function f(bool cond, uint v) returns (uint a, uint b) { cond ? a = v : b = v; - } + } })"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("f(bool,uint256)", true, u256(20)) == encodeArgs(u256(20), u256(0))); @@ -169,7 +178,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_storage_memory_1) } return ret; - } + } } )"; compileAndRun(sourceCode); @@ -203,7 +212,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_storage_memory_2) } return ret; - } + } } )"; compileAndRun(sourceCode); @@ -219,7 +228,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_different_types) uint8 x = 0xcd; uint16 y = 0xabab; return cond ? x : y; - } + } } )"; compileAndRun(sourceCode); @@ -277,12 +286,14 @@ BOOST_AUTO_TEST_CASE(conditional_expression_functions) BOOST_AUTO_TEST_CASE(recursive_calls) { - char const* sourceCode = "contract test {\n" - " function f(uint n) returns(uint nfac) {\n" - " if (n <= 1) return 1;\n" - " else return n * f(n - 1);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint n) returns(uint nfac) { + if (n <= 1) return 1; + else return n * f(n - 1); + } + } + )"; compileAndRun(sourceCode); function<u256(u256)> recursive_calls_cpp = [&recursive_calls_cpp](u256 const& n) -> u256 { @@ -297,12 +308,14 @@ BOOST_AUTO_TEST_CASE(recursive_calls) BOOST_AUTO_TEST_CASE(multiple_functions) { - char const* sourceCode = "contract test {\n" - " function a() returns(uint n) { return 0; }\n" - " function b() returns(uint n) { return 1; }\n" - " function c() returns(uint n) { return 2; }\n" - " function f() returns(uint n) { return 3; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a() returns(uint n) { return 0; } + function b() returns(uint n) { return 1; } + function c() returns(uint n) { return 2; } + function f() returns(uint n) { return 3; } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("a()", bytes()) == toBigEndian(u256(0))); BOOST_CHECK(callContractFunction("b()", bytes()) == toBigEndian(u256(1))); @@ -313,33 +326,39 @@ BOOST_AUTO_TEST_CASE(multiple_functions) BOOST_AUTO_TEST_CASE(named_args) { - char const* sourceCode = "contract test {\n" - " function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n" - " function b() returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; } + function b() returns (uint r) { r = a({a: 1, b: 2, c: 3}); } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("b()", bytes()) == toBigEndian(u256(123))); } BOOST_AUTO_TEST_CASE(disorder_named_args) { - char const* sourceCode = "contract test {\n" - " function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n" - " function b() returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; } + function b() returns (uint r) { r = a({c: 3, a: 1, b: 2}); } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("b()", bytes()) == toBigEndian(u256(123))); } BOOST_AUTO_TEST_CASE(while_loop) { - char const* sourceCode = "contract test {\n" - " function f(uint n) returns(uint nfac) {\n" - " nfac = 1;\n" - " var i = 2;\n" - " while (i <= n) nfac *= i++;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint n) returns(uint nfac) { + nfac = 1; + var i = 2; + while (i <= n) nfac *= i++; + } + } + )"; compileAndRun(sourceCode); auto while_loop_cpp = [](u256 const& n) -> u256 @@ -358,13 +377,15 @@ BOOST_AUTO_TEST_CASE(while_loop) BOOST_AUTO_TEST_CASE(do_while_loop) { - char const* sourceCode = "contract test {\n" - " function f(uint n) returns(uint nfac) {\n" - " nfac = 1;\n" - " var i = 2;\n" - " do { nfac *= i++; } while (i <= n);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint n) returns(uint nfac) { + nfac = 1; + var i = 2; + do { nfac *= i++; } while (i <= n); + } + } + )"; compileAndRun(sourceCode); auto do_while_loop_cpp = [](u256 const& n) -> u256 @@ -386,26 +407,28 @@ BOOST_AUTO_TEST_CASE(do_while_loop) BOOST_AUTO_TEST_CASE(nested_loops) { // tests that break and continue statements in nested loops jump to the correct place - char const* sourceCode = "contract test {\n" - " function f(uint x) returns(uint y) {\n" - " while (x > 1) {\n" - " if (x == 10) break;\n" - " while (x > 5) {\n" - " if (x == 8) break;\n" - " x--;\n" - " if (x == 6) continue;\n" - " return x;\n" - " }\n" - " x--;\n" - " if (x == 3) continue;\n" - " break;\n" - " }\n" - " return x;\n" - " }\n" - "}\n"; - compileAndRun(sourceCode); - - auto nested_loops_cpp = [](u256 n) -> u256 + char const* sourceCode = R"( + contract test { + function f(uint x) returns(uint y) { + while (x > 1) { + if (x == 10) break; + while (x > 5) { + if (x == 8) break; + x--; + if (x == 6) continue; + return x; + } + x--; + if (x == 3) continue; + break; + } + return x; + } + } + )"; + compileAndRun(sourceCode); + + auto nested_loops_cpp = [](u256 n) -> u256 { while (n > 1) { @@ -434,13 +457,15 @@ BOOST_AUTO_TEST_CASE(nested_loops) BOOST_AUTO_TEST_CASE(for_loop) { - char const* sourceCode = "contract test {\n" - " function f(uint n) returns(uint nfac) {\n" - " nfac = 1;\n" - " for (var i = 2; i <= n; i++)\n" - " nfac *= i;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint n) returns(uint nfac) { + nfac = 1; + for (var i = 2; i <= n; i++) + nfac *= i; + } + } + )"; compileAndRun(sourceCode); auto for_loop_cpp = [](u256 const& n) -> u256 @@ -456,16 +481,17 @@ BOOST_AUTO_TEST_CASE(for_loop) BOOST_AUTO_TEST_CASE(for_loop_empty) { - char const* sourceCode = "contract test {\n" - " function f() returns(uint ret) {\n" - " ret = 1;\n" - " for (;;)\n" - " {\n" - " ret += 1;\n" - " if (ret >= 10) break;\n" - " }\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() returns(uint ret) { + ret = 1; + for (;;) { + ret += 1; + if (ret >= 10) break; + } + } + } + )"; compileAndRun(sourceCode); auto for_loop_empty_cpp = []() -> u256 @@ -484,14 +510,16 @@ BOOST_AUTO_TEST_CASE(for_loop_empty) BOOST_AUTO_TEST_CASE(for_loop_simple_init_expr) { - char const* sourceCode = "contract test {\n" - " function f(uint n) returns(uint nfac) {\n" - " nfac = 1;\n" - " uint256 i;\n" - " for (i = 2; i <= n; i++)\n" - " nfac *= i;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint n) returns(uint nfac) { + nfac = 1; + uint256 i; + for (i = 2; i <= n; i++) + nfac *= i; + } + } + )"; compileAndRun(sourceCode); auto for_loop_simple_init_expr_cpp = [](u256 const& n) -> u256 @@ -554,20 +582,22 @@ BOOST_AUTO_TEST_CASE(for_loop_break_continue) BOOST_AUTO_TEST_CASE(calling_other_functions) { - char const* sourceCode = "contract collatz {\n" - " function run(uint x) returns(uint y) {\n" - " while ((y = x) > 1) {\n" - " if (x % 2 == 0) x = evenStep(x);\n" - " else x = oddStep(x);\n" - " }\n" - " }\n" - " function evenStep(uint x) returns(uint y) {\n" - " return x / 2;\n" - " }\n" - " function oddStep(uint x) returns(uint y) {\n" - " return 3 * x + 1;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract collatz { + function run(uint x) returns(uint y) { + while ((y = x) > 1) { + if (x % 2 == 0) x = evenStep(x); + else x = oddStep(x); + } + } + function evenStep(uint x) returns(uint y) { + return x / 2; + } + function oddStep(uint x) returns(uint y) { + return 3 * x + 1; + } + } + )"; compileAndRun(sourceCode); auto evenStep_cpp = [](u256 const& n) -> u256 @@ -602,13 +632,15 @@ BOOST_AUTO_TEST_CASE(calling_other_functions) BOOST_AUTO_TEST_CASE(many_local_variables) { - char const* sourceCode = "contract test {\n" - " function run(uint x1, uint x2, uint x3) returns(uint y) {\n" - " var a = 0x1; var b = 0x10; var c = 0x100;\n" - " y = a + b + c + x1 + x2 + x3;\n" - " y += b + x2;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function run(uint x1, uint x2, uint x3) returns(uint y) { + var a = 0x1; var b = 0x10; var c = 0x100; + y = a + b + c + x1 + x2 + x3; + y += b + x2; + } + } + )"; compileAndRun(sourceCode); auto f = [](u256 const& x1, u256 const& x2, u256 const& x3) -> u256 { @@ -623,13 +655,15 @@ BOOST_AUTO_TEST_CASE(many_local_variables) BOOST_AUTO_TEST_CASE(packing_unpacking_types) { - char const* sourceCode = "contract test {\n" - " function run(bool a, uint32 b, uint64 c) returns(uint256 y) {\n" - " if (a) y = 1;\n" - " y = y * 0x100000000 | ~b;\n" - " y = y * 0x10000000000000000 | ~c;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function run(bool a, uint32 b, uint64 c) returns(uint256 y) { + if (a) y = 1; + y = y * 0x100000000 | ~b; + y = y * 0x10000000000000000 | ~c; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("run(bool,uint32,uint64)", true, fromHex("0f0f0f0f"), fromHex("f0f0f0f0f0f0f0f0")) == fromHex("00000000000000000000000000000000000000""01""f0f0f0f0""0f0f0f0f0f0f0f0f")); @@ -637,12 +671,14 @@ BOOST_AUTO_TEST_CASE(packing_unpacking_types) BOOST_AUTO_TEST_CASE(packing_signed_types) { - char const* sourceCode = "contract test {\n" - " function run() returns(int8 y) {\n" - " uint8 x = 0xfa;\n" - " return int8(x);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function run() returns(int8 y) { + uint8 x = 0xfa; + return int8(x); + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("run()") == fromHex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa")); @@ -650,23 +686,27 @@ BOOST_AUTO_TEST_CASE(packing_signed_types) BOOST_AUTO_TEST_CASE(multiple_return_values) { - char const* sourceCode = "contract test {\n" - " function run(bool x1, uint x2) returns(uint y1, bool y2, uint y3) {\n" - " y1 = x2; y2 = x1;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function run(bool x1, uint x2) returns(uint y1, bool y2, uint y3) { + y1 = x2; y2 = x1; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("run(bool,uint256)", true, 0xcd) == encodeArgs(0xcd, true, 0)); } BOOST_AUTO_TEST_CASE(short_circuiting) { - char const* sourceCode = "contract test {\n" - " function run(uint x) returns(uint y) {\n" - " x == 0 || ((x = 8) > 0);\n" - " return x;" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function run(uint x) returns(uint y) { + x == 0 || ((x = 8) > 0); + return x; + } + } + )"; compileAndRun(sourceCode); auto short_circuiting_cpp = [](u256 n) -> u256 @@ -680,14 +720,16 @@ BOOST_AUTO_TEST_CASE(short_circuiting) BOOST_AUTO_TEST_CASE(high_bits_cleaning) { - char const* sourceCode = "contract test {\n" - " function run() returns(uint256 y) {\n" - " uint32 t = uint32(0xffffffff);\n" - " uint32 x = t + 10;\n" - " if (x >= 0xffffffff) return 0;\n" - " return x;" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function run() returns(uint256 y) { + uint32 t = uint32(0xffffffff); + uint32 x = t + 10; + if (x >= 0xffffffff) return 0; + return x; + } + } + )"; compileAndRun(sourceCode); auto high_bits_cleaning_cpp = []() -> u256 { @@ -702,13 +744,15 @@ BOOST_AUTO_TEST_CASE(high_bits_cleaning) BOOST_AUTO_TEST_CASE(sign_extension) { - char const* sourceCode = "contract test {\n" - " function run() returns(uint256 y) {\n" - " int64 x = -int32(0xff);\n" - " if (x >= 0xff) return 0;\n" - " return -uint256(x);" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function run() returns(uint256 y) { + int64 x = -int32(0xff); + if (x >= 0xff) return 0; + return -uint256(x); + } + } + )"; compileAndRun(sourceCode); auto sign_extension_cpp = []() -> u256 { @@ -722,13 +766,15 @@ BOOST_AUTO_TEST_CASE(sign_extension) BOOST_AUTO_TEST_CASE(small_unsigned_types) { - char const* sourceCode = "contract test {\n" - " function run() returns(uint256 y) {\n" - " uint32 t = uint32(0xffffff);\n" - " uint32 x = t * 0xffffff;\n" - " return x / 0x100;" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function run() returns(uint256 y) { + uint32 t = uint32(0xffffff); + uint32 x = t * 0xffffff; + return x / 0x100; + } + } + )"; compileAndRun(sourceCode); auto small_unsigned_types_cpp = []() -> u256 { @@ -741,11 +787,13 @@ BOOST_AUTO_TEST_CASE(small_unsigned_types) BOOST_AUTO_TEST_CASE(small_signed_types) { - char const* sourceCode = "contract test {\n" - " function run() returns(int256 y) {\n" - " return -int32(10) * -int64(20);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function run() returns(int256 y) { + return -int32(10) * -int64(20); + } + } + )"; compileAndRun(sourceCode); auto small_signed_types_cpp = []() -> u256 { @@ -756,15 +804,17 @@ BOOST_AUTO_TEST_CASE(small_signed_types) BOOST_AUTO_TEST_CASE(strings) { - char const* sourceCode = "contract test {\n" - " function fixedBytes() returns(bytes32 ret) {\n" - " return \"abc\\x00\\xff__\";\n" - " }\n" - " function pipeThrough(bytes2 small, bool one) returns(bytes16 large, bool oneRet) {\n" - " oneRet = one;\n" - " large = small;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function fixedBytes() returns(bytes32 ret) { + return "abc\x00\xff__"; + } + function pipeThrough(bytes2 small, bool one) returns(bytes16 large, bool oneRet) { + oneRet = one; + large = small; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("fixedBytes()") == encodeArgs(string("abc\0\xff__", 7))); BOOST_CHECK(callContractFunction("pipeThrough(bytes2,bool)", string("\0\x02", 2), true) == encodeArgs(string("\0\x2", 2), true)); @@ -809,18 +859,20 @@ BOOST_AUTO_TEST_CASE(bytes_comparison) BOOST_AUTO_TEST_CASE(state_smoke_test) { - char const* sourceCode = "contract test {\n" - " uint256 value1;\n" - " uint256 value2;\n" - " function get(uint8 which) returns (uint256 value) {\n" - " if (which == 0) return value1;\n" - " else return value2;\n" - " }\n" - " function set(uint8 which, uint256 value) {\n" - " if (which == 0) value1 = value;\n" - " else value2 = value;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + uint256 value1; + uint256 value2; + function get(uint8 which) returns (uint256 value) { + if (which == 0) return value1; + else return value2; + } + function set(uint8 which, uint256 value) { + if (which == 0) value1 = value; + else value2 = value; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("get(uint8)", byte(0x00)) == encodeArgs(0)); BOOST_CHECK(callContractFunction("get(uint8)", byte(0x01)) == encodeArgs(0)); @@ -834,17 +886,19 @@ BOOST_AUTO_TEST_CASE(state_smoke_test) BOOST_AUTO_TEST_CASE(compound_assign) { - char const* sourceCode = "contract test {\n" - " uint value1;\n" - " uint value2;\n" - " function f(uint x, uint y) returns (uint w) {\n" - " uint value3 = y;" - " value1 += x;\n" - " value3 *= x;" - " value2 *= value3 + value1;\n" - " return value2 += 7;" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + uint value1; + uint value2; + function f(uint x, uint y) returns (uint w) { + uint value3 = y; + value1 += x; + value3 *= x; + value2 *= value3 + value1; + return value2 += 7; + } + } + )"; compileAndRun(sourceCode); u256 value1; @@ -869,15 +923,17 @@ BOOST_AUTO_TEST_CASE(compound_assign) BOOST_AUTO_TEST_CASE(simple_mapping) { - char const* sourceCode = "contract test {\n" - " mapping(uint8 => uint8) table;\n" - " function get(uint8 k) returns (uint8 v) {\n" - " return table[k];\n" - " }\n" - " function set(uint8 k, uint8 v) {\n" - " table[k] = v;\n" - " }\n" - "}"; + char const* sourceCode = R"( + contract test { + mapping(uint8 => uint8) table; + function get(uint8 k) returns (uint8 v) { + return table[k]; + } + function set(uint8 k, uint8 v) { + table[k] = v; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("get(uint8)", byte(0)) == encodeArgs(byte(0x00))); @@ -899,23 +955,25 @@ BOOST_AUTO_TEST_CASE(simple_mapping) BOOST_AUTO_TEST_CASE(mapping_state) { - char const* sourceCode = "contract Ballot {\n" - " mapping(address => bool) canVote;\n" - " mapping(address => uint) voteCount;\n" - " mapping(address => bool) voted;\n" - " function getVoteCount(address addr) returns (uint retVoteCount) {\n" - " return voteCount[addr];\n" - " }\n" - " function grantVoteRight(address addr) {\n" - " canVote[addr] = true;\n" - " }\n" - " function vote(address voter, address vote) returns (bool success) {\n" - " if (!canVote[voter] || voted[voter]) return false;\n" - " voted[voter] = true;\n" - " voteCount[vote] = voteCount[vote] + 1;\n" - " return true;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract Ballot { + mapping(address => bool) canVote; + mapping(address => uint) voteCount; + mapping(address => bool) voted; + function getVoteCount(address addr) returns (uint retVoteCount) { + return voteCount[addr]; + } + function grantVoteRight(address addr) { + canVote[addr] = true; + } + function vote(address voter, address vote) returns (bool success) { + if (!canVote[voter] || voted[voter]) return false; + voted[voter] = true; + voteCount[vote] = voteCount[vote] + 1; + return true; + } + } + )"; compileAndRun(sourceCode); class Ballot { @@ -974,17 +1032,19 @@ BOOST_AUTO_TEST_CASE(mapping_state) BOOST_AUTO_TEST_CASE(mapping_state_inc_dec) { - char const* sourceCode = "contract test {\n" - " uint value;\n" - " mapping(uint => uint) table;\n" - " function f(uint x) returns (uint y) {\n" - " value = x;\n" - " if (x > 0) table[++value] = 8;\n" - " if (x > 1) value--;\n" - " if (x > 2) table[value]++;\n" - " return --table[value++];\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + uint value; + mapping(uint => uint) table; + function f(uint x) returns (uint y) { + value = x; + if (x > 0) table[++value] = 8; + if (x > 1) value--; + if (x > 2) table[value]++; + return --table[value++]; + } + } + )"; compileAndRun(sourceCode); u256 value = 0; @@ -1005,13 +1065,15 @@ BOOST_AUTO_TEST_CASE(mapping_state_inc_dec) BOOST_AUTO_TEST_CASE(multi_level_mapping) { - char const* sourceCode = "contract test {\n" - " mapping(uint => mapping(uint => uint)) table;\n" - " function f(uint x, uint y, uint z) returns (uint w) {\n" - " if (z == 0) return table[x][y];\n" - " else return table[x][y] = z;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + mapping(uint => mapping(uint => uint)) table; + function f(uint x, uint y, uint z) returns (uint w) { + if (z == 0) return table[x][y]; + else return table[x][y] = z; + } + } + )"; compileAndRun(sourceCode); map<u256, map<u256, u256>> table; @@ -1032,35 +1094,37 @@ BOOST_AUTO_TEST_CASE(multi_level_mapping) BOOST_AUTO_TEST_CASE(structs) { - char const* sourceCode = "contract test {\n" - " struct s1 {\n" - " uint8 x;\n" - " bool y;\n" - " }\n" - " struct s2 {\n" - " uint32 z;\n" - " s1 s1data;\n" - " mapping(uint8 => s2) recursive;\n" - " }\n" - " s2 data;\n" - " function check() returns (bool ok) {\n" - " return data.z == 1 && data.s1data.x == 2 && \n" - " data.s1data.y == true && \n" - " data.recursive[3].recursive[4].z == 5 && \n" - " data.recursive[4].recursive[3].z == 6 && \n" - " data.recursive[0].s1data.y == false && \n" - " data.recursive[4].z == 9;\n" - " }\n" - " function set() {\n" - " data.z = 1;\n" - " data.s1data.x = 2;\n" - " data.s1data.y = true;\n" - " data.recursive[3].recursive[4].z = 5;\n" - " data.recursive[4].recursive[3].z = 6;\n" - " data.recursive[0].s1data.y = false;\n" - " data.recursive[4].z = 9;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + struct s1 { + uint8 x; + bool y; + } + struct s2 { + uint32 z; + s1 s1data; + mapping(uint8 => s2) recursive; + } + s2 data; + function check() returns (bool ok) { + return data.z == 1 && data.s1data.x == 2 && + data.s1data.y == true && + data.recursive[3].recursive[4].z == 5 && + data.recursive[4].recursive[3].z == 6 && + data.recursive[0].s1data.y == false && + data.recursive[4].z == 9; + } + function set() { + data.z = 1; + data.s1data.x = 2; + data.s1data.y = true; + data.recursive[3].recursive[4].z = 5; + data.recursive[4].recursive[3].z = 6; + data.recursive[0].s1data.y = false; + data.recursive[4].z = 9; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("check()") == encodeArgs(false)); BOOST_CHECK(callContractFunction("set()") == bytes()); @@ -1069,26 +1133,28 @@ BOOST_AUTO_TEST_CASE(structs) BOOST_AUTO_TEST_CASE(struct_reference) { - char const* sourceCode = "contract test {\n" - " struct s2 {\n" - " uint32 z;\n" - " mapping(uint8 => s2) recursive;\n" - " }\n" - " s2 data;\n" - " function check() returns (bool ok) {\n" - " return data.z == 2 && \n" - " data.recursive[0].z == 3 && \n" - " data.recursive[0].recursive[1].z == 0 && \n" - " data.recursive[0].recursive[0].z == 1;\n" - " }\n" - " function set() {\n" - " data.z = 2;\n" - " var map = data.recursive;\n" - " s2 inner = map[0];\n" - " inner.z = 3;\n" - " inner.recursive[0].z = inner.recursive[1].z + 1;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + struct s2 { + uint32 z; + mapping(uint8 => s2) recursive; + } + s2 data; + function check() returns (bool ok) { + return data.z == 2 && + data.recursive[0].z == 3 && + data.recursive[0].recursive[1].z == 0 && + data.recursive[0].recursive[0].z == 1; + } + function set() { + data.z = 2; + var map = data.recursive; + s2 inner = map[0]; + inner.z = 3; + inner.recursive[0].z = inner.recursive[1].z + 1; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("check()") == encodeArgs(false)); BOOST_CHECK(callContractFunction("set()") == bytes()); @@ -1135,12 +1201,13 @@ BOOST_AUTO_TEST_CASE(deleteStruct) nestedValue = str.nstr.nestedValue; } function getTopMapping(uint index) returns(uint ret) { - ret = str.topMapping[index]; + ret = str.topMapping[index]; } function getNestedMapping(uint index) returns(bool ret) { return str.nstr.nestedMapping[index]; } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("getToDelete()") == encodeArgs(0)); BOOST_CHECK(callContractFunction("getTopValue()") == encodeArgs(0)); @@ -1161,7 +1228,8 @@ BOOST_AUTO_TEST_CASE(deleteLocal) delete v; res = v; } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("delLocal()") == encodeArgs(0)); } @@ -1178,22 +1246,25 @@ BOOST_AUTO_TEST_CASE(deleteLocals) res1 = w; res2 = x; } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("delLocal()") == encodeArgs(6, 7)); } BOOST_AUTO_TEST_CASE(constructor) { - char const* sourceCode = "contract test {\n" - " mapping(uint => uint) data;\n" - " function test() {\n" - " data[7] = 8;\n" - " }\n" - " function get(uint key) returns (uint value) {\n" - " return data[key];" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + mapping(uint => uint) data; + function test() { + data[7] = 8; + } + function get(uint key) returns (uint value) { + return data[key]; + } + } + )"; compileAndRun(sourceCode); map<u256, byte> data; data[7] = 8; @@ -1207,12 +1278,14 @@ BOOST_AUTO_TEST_CASE(constructor) BOOST_AUTO_TEST_CASE(simple_accessor) { - char const* sourceCode = "contract test {\n" - " uint256 public data;\n" - " function test() {\n" - " data = 8;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + uint256 public data; + function test() { + data = 8; + } + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data()") == encodeArgs(8)); } @@ -1254,7 +1327,7 @@ BOOST_AUTO_TEST_CASE(array_accessor) BOOST_AUTO_TEST_CASE(accessors_mapping_for_array) { char const* sourceCode = R"( - contract test { + contract test { mapping(uint => uint[8]) public data; mapping(uint => uint[]) public dynamicData; function test() { @@ -1262,7 +1335,7 @@ BOOST_AUTO_TEST_CASE(accessors_mapping_for_array) dynamicData[2].length = 3; dynamicData[2][2] = 8; } - } + } )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data(uint256,uint256)", 2, 2) == encodeArgs(8)); @@ -1273,20 +1346,22 @@ BOOST_AUTO_TEST_CASE(accessors_mapping_for_array) BOOST_AUTO_TEST_CASE(multiple_elementary_accessors) { - char const* sourceCode = "contract test {\n" - " uint256 public data;\n" - " bytes6 public name;\n" - " bytes32 public a_hash;\n" - " address public an_address;\n" - " function test() {\n" - " data = 8;\n" - " name = \"Celina\";\n" - " a_hash = sha3(123);\n" - " an_address = address(0x1337);\n" - " super_secret_data = 42;\n" - " }\n" - " uint256 super_secret_data;" - "}\n"; + char const* sourceCode = R"( + contract test { + uint256 public data; + bytes6 public name; + bytes32 public a_hash; + address public an_address; + function test() { + data = 8; + name = "Celina"; + a_hash = sha3(123); + an_address = address(0x1337); + super_secret_data = 42; + } + uint256 super_secret_data; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("name()") == encodeArgs("Celina")); @@ -1338,26 +1413,30 @@ BOOST_AUTO_TEST_CASE(struct_accessor) BOOST_AUTO_TEST_CASE(balance) { - char const* sourceCode = "contract test {\n" - " function test() payable {}\n" - " function getBalance() returns (uint256 balance) {\n" - " return address(this).balance;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function test() payable {} + function getBalance() returns (uint256 balance) { + return address(this).balance; + } + } + )"; compileAndRun(sourceCode, 23); BOOST_CHECK(callContractFunction("getBalance()") == encodeArgs(23)); } BOOST_AUTO_TEST_CASE(blockchain) { - char const* sourceCode = "contract test {\n" - " function test() payable {}\n" - " function someInfo() payable returns (uint256 value, address coinbase, uint256 blockNumber) {\n" - " value = msg.value;\n" - " coinbase = block.coinbase;\n" - " blockNumber = block.number;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function test() payable {} + function someInfo() payable returns (uint256 value, address coinbase, uint256 blockNumber) { + value = msg.value; + coinbase = block.coinbase; + blockNumber = block.number; + } + } + )"; BOOST_CHECK(m_rpc.rpcCall("miner_setEtherbase", {"\"0x1212121212121212121212121212121212121212\""}).asBool() == true); m_rpc.test_mineBlocks(5); compileAndRun(sourceCode, 27); @@ -1395,12 +1474,14 @@ BOOST_AUTO_TEST_CASE(msg_sig_after_internal_call_is_same) BOOST_AUTO_TEST_CASE(now) { - char const* sourceCode = "contract test {\n" - " function someInfo() returns (bool equal, uint val) {\n" - " equal = block.timestamp == now;\n" - " val = now;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function someInfo() returns (bool equal, uint val) { + equal = block.timestamp == now; + val = now; + } + } + )"; m_rpc.test_modifyTimestamp(0x776347e2); compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("someInfo()") == encodeArgs(true, 0x776347e3)); @@ -1413,7 +1494,8 @@ BOOST_AUTO_TEST_CASE(type_conversions_cleanup) char const* sourceCode = R"( contract Test { function test() returns (uint ret) { return uint(address(Test(address(0x11223344556677889900112233445566778899001122)))); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_REQUIRE(callContractFunction("test()") == bytes({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, @@ -1427,7 +1509,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_fixed_bytes_smaller_size) function bytesToBytes(bytes4 input) returns (bytes2 ret) { return bytes2(input); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("bytesToBytes(bytes4)", "abcd") == encodeArgs("ab")); } @@ -1439,7 +1522,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_fixed_bytes_greater_size) function bytesToBytes(bytes2 input) returns (bytes4 ret) { return bytes4(input); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("bytesToBytes(bytes2)", "ab") == encodeArgs("ab")); } @@ -1451,7 +1535,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_fixed_bytes_same_size) function bytesToBytes(bytes4 input) returns (bytes4 ret) { return bytes4(input); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("bytesToBytes(bytes4)", "abcd") == encodeArgs("abcd")); } @@ -1464,7 +1549,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_same_size) function bytesToUint(bytes32 s) returns (uint256 h) { return uint(s); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("bytesToUint(bytes32)", string("abc2")) == encodeArgs(u256("0x6162633200000000000000000000000000000000000000000000000000000000"))); @@ -1477,7 +1563,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_same_min_size) function bytesToUint(bytes1 s) returns (uint8 h) { return uint8(s); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("bytesToUint(bytes1)", string("a")) == encodeArgs(u256("0x61"))); @@ -1490,7 +1577,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_smaller_size) function bytesToUint(bytes4 s) returns (uint16 h) { return uint16(s); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("bytesToUint(bytes4)", string("abcd")) == encodeArgs(u256("0x6364"))); @@ -1503,7 +1591,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_greater_size) function bytesToUint(bytes4 s) returns (uint64 h) { return uint64(s); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("bytesToUint(bytes4)", string("abcd")) == encodeArgs(u256("0x61626364"))); @@ -1517,7 +1606,8 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_same_size) function uintToBytes(uint256 h) returns (bytes32 s) { return bytes32(h); } - })"; + } + )"; compileAndRun(sourceCode); u256 a("0x6162630000000000000000000000000000000000000000000000000000000000"); BOOST_CHECK(callContractFunction("uintToBytes(uint256)", a) == encodeArgs(a)); @@ -1530,7 +1620,8 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_same_min_size) function UintToBytes(uint8 h) returns (bytes1 s) { return bytes1(h); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("UintToBytes(uint8)", u256("0x61")) == encodeArgs(string("a"))); @@ -1543,7 +1634,8 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_smaller_size) function uintToBytes(uint32 h) returns (bytes2 s) { return bytes2(h); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("uintToBytes(uint32)", u160("0x61626364")) == encodeArgs(string("cd"))); @@ -1556,7 +1648,8 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_greater_size) function UintToBytes(uint16 h) returns (bytes8 s) { return bytes8(h); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK( callContractFunction("UintToBytes(uint16)", u256("0x6162")) == @@ -1566,13 +1659,15 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_greater_size) BOOST_AUTO_TEST_CASE(send_ether) { - char const* sourceCode = "contract test {\n" - " function test() payable {}\n" - " function a(address addr, uint amount) returns (uint ret) {\n" - " addr.send(amount);\n" - " return address(this).balance;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function test() payable {} + function a(address addr, uint amount) returns (uint ret) { + addr.send(amount); + return address(this).balance; + } + } + )"; u256 amount(130); compileAndRun(sourceCode, amount + 1); u160 address(23); @@ -1582,11 +1677,13 @@ BOOST_AUTO_TEST_CASE(send_ether) BOOST_AUTO_TEST_CASE(log0) { - char const* sourceCode = "contract test {\n" - " function a() {\n" - " log0(1);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a() { + log0(1); + } + } + )"; compileAndRun(sourceCode); callContractFunction("a()"); BOOST_REQUIRE_EQUAL(m_logs.size(), 1); @@ -1597,11 +1694,13 @@ BOOST_AUTO_TEST_CASE(log0) BOOST_AUTO_TEST_CASE(log1) { - char const* sourceCode = "contract test {\n" - " function a() {\n" - " log1(1, 2);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a() { + log1(1, 2); + } + } + )"; compileAndRun(sourceCode); callContractFunction("a()"); BOOST_REQUIRE_EQUAL(m_logs.size(), 1); @@ -1613,11 +1712,13 @@ BOOST_AUTO_TEST_CASE(log1) BOOST_AUTO_TEST_CASE(log2) { - char const* sourceCode = "contract test {\n" - " function a() {\n" - " log2(1, 2, 3);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a() { + log2(1, 2, 3); + } + } + )"; compileAndRun(sourceCode); callContractFunction("a()"); BOOST_REQUIRE_EQUAL(m_logs.size(), 1); @@ -1630,11 +1731,13 @@ BOOST_AUTO_TEST_CASE(log2) BOOST_AUTO_TEST_CASE(log3) { - char const* sourceCode = "contract test {\n" - " function a() {\n" - " log3(1, 2, 3, 4);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a() { + log3(1, 2, 3, 4); + } + } + )"; compileAndRun(sourceCode); callContractFunction("a()"); BOOST_REQUIRE_EQUAL(m_logs.size(), 1); @@ -1647,11 +1750,13 @@ BOOST_AUTO_TEST_CASE(log3) BOOST_AUTO_TEST_CASE(log4) { - char const* sourceCode = "contract test {\n" - " function a() {\n" - " log4(1, 2, 3, 4, 5);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a() { + log4(1, 2, 3, 4, 5); + } + } + )"; compileAndRun(sourceCode); callContractFunction("a()"); BOOST_REQUIRE_EQUAL(m_logs.size(), 1); @@ -1664,11 +1769,13 @@ BOOST_AUTO_TEST_CASE(log4) BOOST_AUTO_TEST_CASE(log_in_constructor) { - char const* sourceCode = "contract test {\n" - " function test() {\n" - " log1(1, 2);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function test() { + log1(1, 2); + } + } + )"; compileAndRun(sourceCode); BOOST_REQUIRE_EQUAL(m_logs.size(), 1); BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); @@ -1679,13 +1786,15 @@ BOOST_AUTO_TEST_CASE(log_in_constructor) BOOST_AUTO_TEST_CASE(suicide) { - char const* sourceCode = "contract test {\n" - " function test() payable {}\n" - " function a(address receiver) returns (uint ret) {\n" - " suicide(receiver);\n" - " return 10;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function test() payable {} + function a(address receiver) returns (uint ret) { + suicide(receiver); + return 10; + } + } + )"; u256 amount(130); compileAndRun(sourceCode, amount); u160 address(23); @@ -1696,13 +1805,15 @@ BOOST_AUTO_TEST_CASE(suicide) BOOST_AUTO_TEST_CASE(selfdestruct) { - char const* sourceCode = "contract test {\n" - " function test() payable {}\n" - " function a(address receiver) returns (uint ret) {\n" - " selfdestruct(receiver);\n" - " return 10;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function test() payable {} + function a(address receiver) returns (uint ret) { + selfdestruct(receiver); + return 10; + } + } + )"; u256 amount(130); compileAndRun(sourceCode, amount); u160 address(23); @@ -1713,11 +1824,13 @@ BOOST_AUTO_TEST_CASE(selfdestruct) BOOST_AUTO_TEST_CASE(sha3) { - char const* sourceCode = "contract test {\n" - " function a(bytes32 input) returns (bytes32 sha3hash) {\n" - " return sha3(input);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(bytes32 input) returns (bytes32 sha3hash) { + return sha3(input); + } + } + )"; compileAndRun(sourceCode); auto f = [&](u256 const& _x) -> u256 { @@ -1730,11 +1843,13 @@ BOOST_AUTO_TEST_CASE(sha3) BOOST_AUTO_TEST_CASE(sha256) { - char const* sourceCode = "contract test {\n" - " function a(bytes32 input) returns (bytes32 sha256hash) {\n" - " return sha256(input);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(bytes32 input) returns (bytes32 sha256hash) { + return sha256(input); + } + } + )"; compileAndRun(sourceCode); auto f = [&](u256 const& _x) -> bytes { @@ -1753,11 +1868,13 @@ BOOST_AUTO_TEST_CASE(sha256) BOOST_AUTO_TEST_CASE(ripemd) { - char const* sourceCode = "contract test {\n" - " function a(bytes32 input) returns (bytes32 sha256hash) {\n" - " return ripemd160(input);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(bytes32 input) returns (bytes32 sha256hash) { + return ripemd160(input); + } + } + )"; compileAndRun(sourceCode); auto f = [&](u256 const& _x) -> bytes { @@ -1776,11 +1893,13 @@ BOOST_AUTO_TEST_CASE(ripemd) BOOST_AUTO_TEST_CASE(ecrecover) { - char const* sourceCode = "contract test {\n" - " function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) returns (address addr) {\n" - " return ecrecover(h, v, r, s);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) returns (address addr) { + return ecrecover(h, v, r, s); + } + } + )"; compileAndRun(sourceCode); u256 h("0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c"); byte v = 28; @@ -2798,7 +2917,8 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one) ret_k = k; ret_g = g; } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("f(uint256,uint256)", 5, 9) != encodeArgs(5, 8)); BOOST_CHECK(callContractFunction("f(uint256,uint256)", 5, 9) == encodeArgs(9, 8)); @@ -2811,7 +2931,8 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter) function f(uint k) returns(uint){ return k; } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("f(uint256)", 9) == encodeArgs(9)); } @@ -2824,7 +2945,8 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments) { d = sha3(a, b, c); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("foo(uint256,uint256,uint256)", 10, 12, 13) == encodeArgs( @@ -2842,7 +2964,8 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals) { d = sha3(a, b, 145); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("foo(uint256,uint16)", 10, 12) == encodeArgs( @@ -2864,7 +2987,8 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) { d = sha3(a, b, 145, "foo"); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("foo()") == encodeArgs(dev::keccak256("foo"))); @@ -2890,7 +3014,8 @@ BOOST_AUTO_TEST_CASE(sha3_with_bytes) data[2] = "o"; return sha3(data) == sha3("foo"); } - })"; + } + )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("foo()") == encodeArgs(true)); } @@ -6450,17 +6575,6 @@ BOOST_AUTO_TEST_CASE(calldata_offset) BOOST_CHECK(callContractFunction("last()", encodeArgs()) == encodeDyn(string("nd"))); } -BOOST_AUTO_TEST_CASE(version_stamp_for_libraries) -{ - char const* sourceCode = "library lib {}"; - m_optimize = true; - bytes runtimeCode = compileAndRun(sourceCode, 0, "lib"); - BOOST_CHECK(runtimeCode.size() >= 8); - BOOST_CHECK_EQUAL(runtimeCode[0], int(Instruction::PUSH6)); // might change once we switch to 1.x.x - BOOST_CHECK_EQUAL(runtimeCode[1], 4); // might change once we switch away from x.4.x - BOOST_CHECK_EQUAL(runtimeCode[7], int(Instruction::POP)); -} - BOOST_AUTO_TEST_CASE(contract_binary_dependencies) { char const* sourceCode = R"( @@ -7734,13 +7848,6 @@ BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call) u160 cAddr = m_contractAddress; compileAndRun(sourceCode, 0, "D"); BOOST_CHECK(callContractFunction("f(address)", cAddr) == encodeArgs(u256(7))); - - m_optimize = true; - - compileAndRun(sourceCode, 0, "C"); - u160 cAddrOpt = m_contractAddress; - compileAndRun(sourceCode, 0, "D"); - BOOST_CHECK(callContractFunction("f(address)", cAddrOpt) == encodeArgs(u256(7))); } BOOST_AUTO_TEST_CASE(calling_uninitialized_function) @@ -8406,6 +8513,18 @@ BOOST_AUTO_TEST_CASE(inline_assembly_invalidjumplabel) BOOST_CHECK(callContractFunction("f()") == encodeArgs()); } +BOOST_AUTO_TEST_CASE(contracts_separated_with_comment) +{ + char const* sourceCode = R"( + contract C1 {} + /** + **/ + contract C2 {} + )"; + compileAndRun(sourceCode, 0, "C1"); + compileAndRun(sourceCode, 0, "C2"); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityExecutionFramework.h b/test/libsolidity/SolidityExecutionFramework.h index 0fab7aeb..03e3a881 100644 --- a/test/libsolidity/SolidityExecutionFramework.h +++ b/test/libsolidity/SolidityExecutionFramework.h @@ -56,7 +56,7 @@ public: std::string sourceCode = "pragma solidity >=0.0;\n" + _sourceCode; m_compiler.reset(false); m_compiler.addSource("", sourceCode); - if (!m_compiler.compile(m_optimize, m_optimizeRuns)) + if (!m_compiler.compile(m_optimize, m_optimizeRuns, _libraryAddresses)) { for (auto const& error: m_compiler.errors()) SourceReferenceFormatter::printExceptionInformation( @@ -68,7 +68,6 @@ public: BOOST_ERROR("Compiling contract failed"); } eth::LinkerObject obj = m_compiler.object(_contractName); - obj.link(_libraryAddresses); BOOST_REQUIRE(obj.linkReferences.empty()); sendMessage(obj.bytecode + _arguments, true, _value); return m_output; diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index cab9f09f..0c5a09c3 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -168,9 +168,11 @@ BOOST_AUTO_TEST_SUITE(SolidityExpressionCompiler) BOOST_AUTO_TEST_CASE(literal_true) { - char const* sourceCode = "contract test {\n" - " function f() { var x = true; }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = true; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH1), 0x1}); @@ -179,9 +181,11 @@ BOOST_AUTO_TEST_CASE(literal_true) BOOST_AUTO_TEST_CASE(literal_false) { - char const* sourceCode = "contract test {\n" - " function f() { var x = false; }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = false; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH1), 0x0}); @@ -190,9 +194,11 @@ BOOST_AUTO_TEST_CASE(literal_false) BOOST_AUTO_TEST_CASE(int_literal) { - char const* sourceCode = "contract test {\n" - " function f() { var x = 0x12345678901234567890; }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = 0x12345678901234567890; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH10), 0x12, 0x34, 0x56, 0x78, 0x90, @@ -204,11 +210,11 @@ BOOST_AUTO_TEST_CASE(int_with_wei_ether_subdenomination) { char const* sourceCode = R"( contract test { - function test () - { + function test () { var x = 1 wei; } - })"; + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH1), 0x1}); @@ -219,11 +225,11 @@ BOOST_AUTO_TEST_CASE(int_with_szabo_ether_subdenomination) { char const* sourceCode = R"( contract test { - function test () - { + function test () { var x = 1 szabo; } - })"; + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH5), 0xe8, 0xd4, 0xa5, 0x10, 0x00}); @@ -249,11 +255,11 @@ BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination) { char const* sourceCode = R"( contract test { - function test () - { + function test () { var x = 1 ether; } - })"; + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00}); @@ -262,9 +268,11 @@ BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination) BOOST_AUTO_TEST_CASE(comparison) { - char const* sourceCode = "contract test {\n" - " function f() { var x = (0x10aa < 0x11aa) != true; }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = (0x10aa < 0x11aa) != true; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH1), 0x1, byte(Instruction::ISZERO), byte(Instruction::ISZERO), @@ -278,9 +286,11 @@ BOOST_AUTO_TEST_CASE(comparison) BOOST_AUTO_TEST_CASE(short_circuiting) { - char const* sourceCode = "contract test {\n" - " function f() { var x = true != (4 <= 8 + 10 || 9 != 2); }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = true != (4 <= 8 + 10 || 9 != 2); } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation({byte(Instruction::PUSH1), 0x12, // 8 + 10 @@ -305,9 +315,11 @@ BOOST_AUTO_TEST_CASE(short_circuiting) BOOST_AUTO_TEST_CASE(arithmetics) { - char const* sourceCode = "contract test {\n" - " function f(uint y) { var x = ((((((((y ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint y) { var x = ((((((((y ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); } + } + )"; bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}, {"test", "f", "x"}}); bytes expectation({byte(Instruction::PUSH1), 0x1, byte(Instruction::PUSH1), 0x2, @@ -339,9 +351,11 @@ BOOST_AUTO_TEST_CASE(arithmetics) BOOST_AUTO_TEST_CASE(unary_operators) { - char const* sourceCode = "contract test {\n" - " function f(int y) { var x = !(~+- y == 2); }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(int y) { var x = !(~+- y == 2); } + } + )"; bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}, {"test", "f", "x"}}); bytes expectation({byte(Instruction::PUSH1), 0x2, @@ -356,9 +370,11 @@ BOOST_AUTO_TEST_CASE(unary_operators) BOOST_AUTO_TEST_CASE(unary_inc_dec) { - char const* sourceCode = "contract test {\n" - " function f(uint a) { var x = --a ^ (a-- ^ (++a ^ a++)); }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a) { var x = --a ^ (a-- ^ (++a ^ a++)); } + } + )"; bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "x"}}); // Stack: a, x @@ -406,9 +422,11 @@ BOOST_AUTO_TEST_CASE(unary_inc_dec) BOOST_AUTO_TEST_CASE(assignment) { - char const* sourceCode = "contract test {\n" - " function f(uint a, uint b) { (a += b) * 2; }" - "}\n"; + char const* sourceCode = R"( + contract test { + function f(uint a, uint b) { (a += b) * 2; } + } + )"; bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "b"}}); // Stack: a, b @@ -427,9 +445,11 @@ BOOST_AUTO_TEST_CASE(assignment) BOOST_AUTO_TEST_CASE(negative_literals_8bits) { - char const* sourceCode = "contract test {\n" - " function f() { int8 x = -0x80; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { int8 x = -0x80; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation(bytes({byte(Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80)); @@ -438,9 +458,11 @@ BOOST_AUTO_TEST_CASE(negative_literals_8bits) BOOST_AUTO_TEST_CASE(negative_literals_16bits) { - char const* sourceCode = "contract test {\n" - " function f() { int64 x = ~0xabc; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { int64 x = ~0xabc; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation(bytes({byte(Instruction::PUSH32)}) + bytes(30, 0xff) + bytes{0xf5, 0x43}); @@ -451,9 +473,11 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals) { // first literal itself is too large for 256 bits but it fits after all constant operations // have been applied - char const* sourceCode = "contract test {\n" - " function f() { var x = (0xffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { var x = (0xffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; } + } + )"; bytes code = compileFirstExpression(sourceCode); bytes expectation(bytes({byte(Instruction::PUSH1), 0xbf})); @@ -462,11 +486,13 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals) BOOST_AUTO_TEST_CASE(blockhash) { - char const* sourceCode = "contract test {\n" - " function f() {\n" - " block.blockhash(3);\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function f() { + block.blockhash(3); + } + } + )"; bytes code = compileFirstExpression(sourceCode, {}, {}, {make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::Block))}); diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 7a132068..11c38114 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -46,7 +46,7 @@ namespace { pair<ASTPointer<SourceUnit>, std::shared_ptr<Error const>> -parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false, bool _insertVersionPragma = true) +parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false, bool _insertVersionPragma = true, bool _allowMultipleErrors = false) { // Silence compiler version warning string source = _insertVersionPragma ? "pragma solidity >=0.0;\n" + _source : _source; @@ -91,6 +91,8 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false, BOOST_CHECK(success || !errors.empty()); } + if (errors.size() > 1 && !_allowMultipleErrors) + BOOST_FAIL("Multiple errors found"); for (auto const& currentError: errors) { if ( @@ -131,9 +133,9 @@ bool success(string const& _source) return !parseAnalyseAndReturnError(_source).second; } -Error expectError(std::string const& _source, bool _warning = false) +Error expectError(std::string const& _source, bool _warning = false, bool _allowMultiple = false) { - auto sourceAndError = parseAnalyseAndReturnError(_source, _warning); + auto sourceAndError = parseAnalyseAndReturnError(_source, _warning, true, _allowMultiple); BOOST_REQUIRE(!!sourceAndError.second); BOOST_REQUIRE(!!sourceAndError.first); return *sourceAndError.second; @@ -151,33 +153,38 @@ static ContractDefinition const* retrieveContract(ASTPointer<SourceUnit> _source } static FunctionTypePointer retrieveFunctionBySignature( - ContractDefinition const* _contract, + ContractDefinition const& _contract, std::string const& _signature ) { FixedHash<4> hash(dev::keccak256(_signature)); - return _contract->interfaceFunctions()[hash]; + return _contract.interfaceFunctions()[hash]; } } -#define CHECK_ERROR_OR_WARNING(text, typ, substring, warning) \ +#define CHECK_ERROR_OR_WARNING(text, typ, substring, warning, allowMulti) \ do \ { \ - Error err = expectError((text), (warning)); \ + Error err = expectError((text), (warning), (allowMulti)); \ BOOST_CHECK(err.type() == (Error::Type::typ)); \ - BOOST_CHECK(searchErrorMessage(err, substring)); \ + BOOST_CHECK(searchErrorMessage(err, (substring))); \ } while(0) // [checkError(text, type, substring)] asserts that the compilation down to typechecking // emits an error of type [type] and with a message containing [substring]. #define CHECK_ERROR(text, type, substring) \ -CHECK_ERROR_OR_WARNING(text, type, substring, false) +CHECK_ERROR_OR_WARNING(text, type, substring, false, false) + +// [checkError(text, type, substring)] asserts that the compilation down to typechecking +// emits an error of type [type] and with a message containing [substring]. +#define CHECK_ERROR_ALLOW_MULTI(text, type, substring) \ +CHECK_ERROR_OR_WARNING(text, type, substring, false, true) // [checkWarning(text, type, substring)] asserts that the compilation down to typechecking // emits a warning of type [type] and with a message containing [substring]. #define CHECK_WARNING(text, substring) \ -CHECK_ERROR_OR_WARNING(text, Warning, substring, true) +CHECK_ERROR_OR_WARNING(text, Warning, substring, true, false) // [checkSuccess(text)] asserts that the compilation down to typechecking succeeds. #define CHECK_SUCCESS(text) do { BOOST_CHECK(success((text))); } while(0) @@ -187,98 +194,123 @@ BOOST_AUTO_TEST_SUITE(SolidityNameAndTypeResolution) BOOST_AUTO_TEST_CASE(smoke_test) { - char const* text = "contract test {\n" - " uint256 stateVariable1;\n" - " function fun(uint256 arg1) { uint256 y; }" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVariable1; + function fun(uint256 arg1) { uint256 y; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(double_stateVariable_declaration) { - char const* text = "contract test {\n" - " uint256 variable;\n" - " uint128 variable;\n" - "}\n"; + char const* text = R"( + contract test { + uint256 variable; + uint128 variable; + } + )"; CHECK_ERROR(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(double_function_declaration) { - char const* text = "contract test {\n" - " function fun() { uint x; }\n" - " function fun() { uint x; }\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { uint x; } + function fun() { uint x; } + } + )"; CHECK_ERROR(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(double_variable_declaration) { - char const* text = "contract test {\n" - " function f() { uint256 x; if (true) { uint256 x; } }\n" - "}\n"; + char const* text = R"( + contract test { + function f() { + uint256 x; + if (true) { uint256 x; } + } + } + )"; CHECK_ERROR(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(name_shadowing) { - char const* text = "contract test {\n" - " uint256 variable;\n" - " function f() { uint32 variable ; }" - "}\n"; + char const* text = R"( + contract test { + uint256 variable; + function f() { uint32 variable; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(name_references) { - char const* text = "contract test {\n" - " uint256 variable;\n" - " function f(uint256 arg) returns (uint out) { f(variable); test; out; }" - "}\n"; + char const* text = R"( + contract test { + uint256 variable; + function f(uint256 arg) returns (uint out) { f(variable); test; out; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(undeclared_name) { - char const* text = "contract test {\n" - " uint256 variable;\n" - " function f(uint256 arg) { f(notfound); }" - "}\n"; + char const* text = R"( + contract test { + uint256 variable; + function f(uint256 arg) { + f(notfound); + } + } + )"; CHECK_ERROR(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(reference_to_later_declaration) { - char const* text = "contract test {\n" - " function g() { f(); }" - " function f() { }" - "}\n"; + char const* text = R"( + contract test { + function g() { f(); } + function f() {} + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive) { - char const* text = "contract test {\n" - " struct MyStructName {\n" - " address addr;\n" - " MyStructName x;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct MyStructName { + address addr; + MyStructName x; + } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive) { - char const* text = "contract test {\n" - " struct MyStructName1 {\n" - " address addr;\n" - " uint256 count;\n" - " MyStructName2 x;\n" - " }\n" - " struct MyStructName2 {\n" - " MyStructName1 x;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct MyStructName1 { + address addr; + uint256 count; + MyStructName2 x; + } + struct MyStructName2 { + MyStructName1 x; + } + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -295,179 +327,216 @@ BOOST_AUTO_TEST_CASE(struct_definition_not_really_recursive) BOOST_AUTO_TEST_CASE(struct_definition_recursion_via_mapping) { - char const* text = "contract test {\n" - " struct MyStructName1 {\n" - " address addr;\n" - " uint256 count;\n" - " mapping(uint => MyStructName1) x;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct MyStructName1 { + address addr; + uint256 count; + mapping(uint => MyStructName1) x; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(type_inference_smoke_test) { - char const* text = "contract test {\n" - " function f(uint256 arg1, uint32 arg2) returns (bool ret) { var x = arg1 + arg2 == 8; ret = x; }" - "}\n"; + char const* text = R"( + contract test { + function f(uint256 arg1, uint32 arg2) returns (bool ret) { + var x = arg1 + arg2 == 8; ret = x; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(type_checking_return) { - char const* text = "contract test {\n" - " function f() returns (bool r) { return 1 >= 2; }" - "}\n"; + char const* text = R"( + contract test { + function f() returns (bool r) { return 1 >= 2; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(type_checking_return_wrong_number) { - char const* text = "contract test {\n" - " function f() returns (bool r1, bool r2) { return 1 >= 2; }" - "}\n"; + char const* text = R"( + contract test { + function f() returns (bool r1, bool r2) { return 1 >= 2; } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(type_checking_return_wrong_type) { - char const* text = "contract test {\n" - " function f() returns (uint256 r) { return 1 >= 2; }" - "}\n"; + char const* text = R"( + contract test { + function f() returns (uint256 r) { return 1 >= 2; } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(type_checking_function_call) { - char const* text = "contract test {\n" - " function f() returns (bool r) { return g(12, true) == 3; }\n" - " function g(uint256 a, bool b) returns (uint256 r) { }\n" - "}\n"; + char const* text = R"( + contract test { + function f() returns (bool r) { return g(12, true) == 3; } + function g(uint256 a, bool b) returns (uint256 r) { } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(type_conversion_for_comparison) { - char const* text = "contract test {\n" - " function f() { uint32(2) == int64(2); }" - "}\n"; + char const* text = R"( + contract test { + function f() { uint32(2) == int64(2); } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(type_conversion_for_comparison_invalid) { - char const* text = "contract test {\n" - " function f() { int32(2) == uint64(2); }" - "}\n"; + char const* text = R"( + contract test { + function f() { int32(2) == uint64(2); } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion) { - char const* text = "contract test {\n" - " function f() returns (int256 r) { var x = int256(uint32(2)); return x; }" - "}\n"; + char const* text = R"( + contract test { + function f() returns (int256 r) { var x = int256(uint32(2)); return x; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(large_string_literal) { - char const* text = "contract test {\n" - " function f() { var x = \"123456789012345678901234567890123\"; }" - "}\n"; + char const* text = R"( + contract test { + function f() { var x = "123456789012345678901234567890123"; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(balance) { - char const* text = "contract test {\n" - " function fun() {\n" - " uint256 x = address(0).balance;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + uint256 x = address(0).balance; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(balance_invalid) { - char const* text = "contract test {\n" - " function fun() {\n" - " address(0).balance = 7;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + address(0).balance = 7; + } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(assignment_to_mapping) { - char const* text = "contract test {\n" - " struct str {\n" - " mapping(uint=>uint) map;\n" - " }\n" - " str data;" - " function fun() {\n" - " var a = data.map;\n" - " data.map = a;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct str { + mapping(uint=>uint) map; + } + str data; + function fun() { + var a = data.map; + data.map = a; + } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(assignment_to_struct) { - char const* text = "contract test {\n" - " struct str {\n" - " mapping(uint=>uint) map;\n" - " }\n" - " str data;" - " function fun() {\n" - " var a = data;\n" - " data = a;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct str { + mapping(uint=>uint) map; + } + str data; + function fun() { + var a = data; + data = a; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(returns_in_constructor) { - char const* text = "contract test {\n" - " function test() returns (uint a) {\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function test() returns (uint a) { } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(forward_function_reference) { - char const* text = "contract First {\n" - " function fun() returns (bool ret) {\n" - " return Second(1).fun(1, true, 3) > 0;\n" - " }\n" - "}\n" - "contract Second {\n" - " function fun(uint a, bool b, uint c) returns (uint ret) {\n" - " if (First(2).fun() == true) return 1;\n" - " }\n" - "}\n"; + char const* text = R"( + contract First { + function fun() returns (bool ret) { + return Second(1).fun(1, true, 3) > 0; + } + } + contract Second { + function fun(uint a, bool b, uint c) returns (uint ret) { + if (First(2).fun() == true) return 1; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(comparison_bitop_precedence) { - char const* text = "contract First {\n" - " function fun() returns (bool ret) {\n" - " return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6;\n" - " }\n" - "}\n"; + char const* text = R"( + contract First { + function fun() returns (bool ret) { + return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6; + } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(function_no_implementation) { ASTPointer<SourceUnit> sourceUnit; - char const* text = "contract test {\n" - " function functionName(bytes32 input) returns (bytes32 out);\n" - "}\n"; + char const* text = R"( + contract test { + function functionName(bytes32 input) returns (bytes32 out); + } + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes(); ContractDefinition* contract = dynamic_cast<ContractDefinition*>(nodes[1].get()); @@ -482,7 +551,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract) char const* text = R"( contract base { function foo(); } contract derived is base { function foo() {} } - )"; + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes(); ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get()); @@ -501,7 +570,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_with_overload) char const* text = R"( contract base { function foo(bool); } contract derived is base { function foo(uint) {} } - )"; + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes(); ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get()); @@ -519,9 +588,9 @@ BOOST_AUTO_TEST_CASE(create_abstract_contract) contract base { function foo(); } contract derived { base b; - function foo() { b = new base();} - } - )"; + function foo() { b = new base(); } + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -535,7 +604,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_optional) function derived(uint i) BaseBase(i){} function foo() {} } - )"; + )"; ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Parsing and name resolving failed"); } @@ -549,7 +618,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_not_provided) function derived(uint i) {} function foo() {} } - )"; + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name resolving failed"); std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes(); BOOST_CHECK_EQUAL(nodes.size(), 4); @@ -565,7 +634,7 @@ BOOST_AUTO_TEST_CASE(redeclare_implemented_abstract_function_as_abstract) contract base { function foo(); } contract derived is base { function foo() {} } contract wrong is derived { function foo(); } - )"; + )"; CHECK_ERROR(text, TypeError, ""); } @@ -587,11 +656,13 @@ BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor) BOOST_AUTO_TEST_CASE(function_canonical_signature) { ASTPointer<SourceUnit> sourceUnit; - char const* text = "contract Test {\n" - " function foo(uint256 arg1, uint64 arg2, bool arg3) returns (uint256 ret) {\n" - " ret = arg1 + arg2;\n" - " }\n" - "}\n"; + char const* text = R"( + contract Test { + function foo(uint256 arg1, uint64 arg2, bool arg3) returns (uint256 ret) { + ret = arg1 + arg2; + } + } + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) @@ -604,11 +675,13 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature) BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases) { ASTPointer<SourceUnit> sourceUnit; - char const* text = "contract Test {\n" - " function boo(uint arg1, bytes32 arg2, address arg3) returns (uint ret) {\n" - " ret = 5;\n" - " }\n" - "}\n"; + char const* text = R"( + contract Test { + function boo(uint arg1, bytes32 arg2, address arg3) returns (uint ret) { + ret = 5; + } + } + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) @@ -629,9 +702,10 @@ BOOST_AUTO_TEST_CASE(function_external_types) } contract Test { function boo(uint arg2, bool arg3, bytes8 arg4, bool[2] pairs, uint[] dynamic, C carg, address[] addresses) external returns (uint ret) { - ret = 5; + ret = 5; } - })"; + } + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) @@ -653,7 +727,8 @@ BOOST_AUTO_TEST_CASE(enum_external_type) function boo(ActionChoices enumArg) external returns (uint ret) { ret = 5; } - })"; + } + )"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed"); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) @@ -670,12 +745,13 @@ BOOST_AUTO_TEST_CASE(function_external_call_allowed_conversion) char const* text = R"( contract C {} contract Test { - function externalCall() { + function externalCall() { C arg; this.g(arg); } function g (C c) external {} - })"; + } + )"; CHECK_SUCCESS(text); } @@ -684,12 +760,13 @@ BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion) char const* text = R"( contract C {} contract Test { - function externalCall() { + function externalCall() { address arg; this.g(arg); } function g (C c) external {} - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -705,7 +782,8 @@ BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion) function internalCall() { g(a); } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -721,18 +799,19 @@ BOOST_AUTO_TEST_CASE(function_internal_not_allowed_conversion) function internalCall() { g(a); } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(hash_collision_in_interface) { - char const* text = "contract test {\n" - " function gsf() {\n" - " }\n" - " function tgeo() {\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function gsf() { } + function tgeo() { } + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -767,7 +846,7 @@ BOOST_AUTO_TEST_CASE(cyclic_inheritance) contract A is B { } contract B is A { } )"; - CHECK_ERROR(text, TypeError, ""); + CHECK_ERROR_ALLOW_MULTI(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(legal_override_direct) @@ -989,26 +1068,28 @@ BOOST_AUTO_TEST_CASE(modifier_returns_value) BOOST_AUTO_TEST_CASE(state_variable_accessors) { - char const* text = "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "uint256 public foo;\n" - "mapping(uint=>bytes4) public map;\n" - "mapping(uint=>mapping(uint=>bytes4)) public multiple_map;\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + uint64(2); + } + uint256 public foo; + mapping(uint=>bytes4) public map; + mapping(uint=>mapping(uint=>bytes4)) public multiple_map; + } + )"; ASTPointer<SourceUnit> source; ContractDefinition const* contract; ETH_TEST_CHECK_NO_THROW(source = parseAndAnalyse(text), "Parsing and Resolving names failed"); BOOST_REQUIRE((contract = retrieveContract(source, 0)) != nullptr); - FunctionTypePointer function = retrieveFunctionBySignature(contract, "foo()"); + FunctionTypePointer function = retrieveFunctionBySignature(*contract, "foo()"); BOOST_REQUIRE(function && function->hasDeclaration()); auto returnParams = function->returnParameterTypeNames(false); BOOST_CHECK_EQUAL(returnParams.at(0), "uint256"); BOOST_CHECK(function->isConstant()); - function = retrieveFunctionBySignature(contract, "map(uint256)"); + function = retrieveFunctionBySignature(*contract, "map(uint256)"); BOOST_REQUIRE(function && function->hasDeclaration()); auto params = function->parameterTypeNames(false); BOOST_CHECK_EQUAL(params.at(0), "uint256"); @@ -1016,7 +1097,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) BOOST_CHECK_EQUAL(returnParams.at(0), "bytes4"); BOOST_CHECK(function->isConstant()); - function = retrieveFunctionBySignature(contract, "multiple_map(uint256,uint256)"); + function = retrieveFunctionBySignature(*contract, "multiple_map(uint256,uint256)"); BOOST_REQUIRE(function && function->hasDeclaration()); params = function->parameterTypeNames(false); BOOST_CHECK_EQUAL(params.at(0), "uint256"); @@ -1028,34 +1109,38 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) BOOST_AUTO_TEST_CASE(function_clash_with_state_variable_accessor) { - char const* text = "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "uint256 foo;\n" - " function foo() {}\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + uint64(2); + } + uint256 foo; + function foo() {} + } + )"; CHECK_ERROR(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(private_state_variable) { - char const* text = "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "uint256 private foo;\n" - "uint256 internal bar;\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + uint64(2); + } + uint256 private foo; + uint256 internal bar; + } + )"; ASTPointer<SourceUnit> source; ContractDefinition const* contract; ETH_TEST_CHECK_NO_THROW(source = parseAndAnalyse(text), "Parsing and Resolving names failed"); BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr); FunctionTypePointer function; - function = retrieveFunctionBySignature(contract, "foo()"); + function = retrieveFunctionBySignature(*contract, "foo()"); BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of a private variable should not exist"); - function = retrieveFunctionBySignature(contract, "bar()"); + function = retrieveFunctionBySignature(*contract, "bar()"); BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of an internal variable should not exist"); } @@ -1075,12 +1160,14 @@ BOOST_AUTO_TEST_CASE(missing_state_variable) BOOST_AUTO_TEST_CASE(base_class_state_variable_accessor) { // test for issue #1126 https://github.com/ethereum/cpp-ethereum/issues/1126 - char const* text = "contract Parent {\n" - " uint256 public m_aMember;\n" - "}\n" - "contract Child is Parent{\n" - " function foo() returns (uint256) { return Parent.m_aMember; }\n" - "}\n"; + char const* text = R"( + contract Parent { + uint256 public m_aMember; + } + contract Child is Parent { + function foo() returns (uint256) { return Parent.m_aMember; } + } + )"; CHECK_SUCCESS(text); } @@ -1088,7 +1175,7 @@ BOOST_AUTO_TEST_CASE(struct_accessor_one_array_only) { char const* sourceCode = R"( contract test { - struct Data { uint[15] m_array; } + struct Data { uint[15] m_array; } Data public data; } )"; @@ -1097,41 +1184,47 @@ BOOST_AUTO_TEST_CASE(struct_accessor_one_array_only) BOOST_AUTO_TEST_CASE(base_class_state_variable_internal_member) { - char const* text = "contract Parent {\n" - " uint256 internal m_aMember;\n" - "}\n" - "contract Child is Parent{\n" - " function foo() returns (uint256) { return Parent.m_aMember; }\n" - "}\n"; + char const* text = R"( + contract Parent { + uint256 internal m_aMember; + } + contract Child is Parent{ + function foo() returns (uint256) { return Parent.m_aMember; } + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class1) { - char const* text = "contract Parent1 {\n" - " uint256 internal m_aMember1;\n" - "}\n" - "contract Parent2 is Parent1{\n" - " uint256 internal m_aMember2;\n" - "}\n" - "contract Child is Parent2{\n" - " function foo() returns (uint256) { return Parent2.m_aMember1; }\n" - "}\n"; + char const* text = R"( + contract Parent1 { + uint256 internal m_aMember1; + } + contract Parent2 is Parent1{ + uint256 internal m_aMember2; + } + contract Child is Parent2{ + function foo() returns (uint256) { return Parent2.m_aMember1; } + } + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class2) { - char const* text = "contract Parent1 {\n" - " uint256 internal m_aMember1;\n" - "}\n" - "contract Parent2 is Parent1{\n" - " uint256 internal m_aMember2;\n" - "}\n" - "contract Child is Parent2{\n" - " function foo() returns (uint256) { return Child.m_aMember2; }\n" - " uint256 public m_aMember3;\n" - "}\n"; + char const* text = R"( + contract Parent1 { + uint256 internal m_aMember1; + } + contract Parent2 is Parent1 { + uint256 internal m_aMember2; + } + contract Child is Parent2 { + function foo() returns (uint256) { return Child.m_aMember2; } + uint256 public m_aMember3; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1197,7 +1290,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_twice) function() { x = 3; } } )"; - CHECK_ERROR(text, DeclarationError, ""); + CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(fallback_function_inheritance) @@ -1220,7 +1313,8 @@ BOOST_AUTO_TEST_CASE(event) contract c { event e(uint indexed a, bytes3 indexed s, bool indexed b); function f() { e(2, "abc", true); } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1229,7 +1323,8 @@ BOOST_AUTO_TEST_CASE(event_too_many_indexed) char const* text = R"( contract c { event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d); - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1238,7 +1333,8 @@ BOOST_AUTO_TEST_CASE(anonymous_event_four_indexed) char const* text = R"( contract c { event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d) anonymous; - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1247,7 +1343,8 @@ BOOST_AUTO_TEST_CASE(anonymous_event_too_many_indexed) char const* text = R"( contract c { event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d, uint indexed e) anonymous; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1257,7 +1354,8 @@ BOOST_AUTO_TEST_CASE(event_call) contract c { event e(uint a, bytes3 indexed s, bool indexed b); function f() { e(2, "abc", true); } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1269,7 +1367,8 @@ BOOST_AUTO_TEST_CASE(event_inheritance) } contract c is base { function f() { e(2, "abc", true); } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1279,7 +1378,8 @@ BOOST_AUTO_TEST_CASE(multiple_events_argument_clash) contract c { event e1(uint a, uint e1, uint e2); event e2(uint a, uint e1, uint e2); - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1291,7 +1391,8 @@ BOOST_AUTO_TEST_CASE(access_to_default_function_visibility) } contract d { function g() { c(0).f(); } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1303,7 +1404,8 @@ BOOST_AUTO_TEST_CASE(access_to_internal_function) } contract d { function g() { c(0).f(); } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1315,7 +1417,8 @@ BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility) } contract d { function g() { c(0).a(); } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1327,43 +1430,68 @@ BOOST_AUTO_TEST_CASE(access_to_internal_state_variable) } contract d { function g() { c(0).a(); } - })"; + } + )"; CHECK_SUCCESS(text); } BOOST_AUTO_TEST_CASE(error_count_in_named_args) { - char const* sourceCode = "contract test {\n" - " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" - " function b() returns (uint r) { r = a({a: 1}); }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(uint a, uint b) returns (uint r) { + r = a + b; + } + function b() returns (uint r) { + r = a({a: 1}); + } + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } BOOST_AUTO_TEST_CASE(empty_in_named_args) { - char const* sourceCode = "contract test {\n" - " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" - " function b() returns (uint r) { r = a({}); }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(uint a, uint b) returns (uint r) { + r = a + b; + } + function b() returns (uint r) { + r = a({}); + } + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } BOOST_AUTO_TEST_CASE(duplicate_parameter_names_in_named_args) { - char const* sourceCode = "contract test {\n" - " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" - " function b() returns (uint r) { r = a({a: 1, a: 2}); }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(uint a, uint b) returns (uint r) { + r = a + b; + } + function b() returns (uint r) { + r = a({a: 1, a: 2}); + } + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } BOOST_AUTO_TEST_CASE(invalid_parameter_names_in_named_args) { - char const* sourceCode = "contract test {\n" - " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" - " function b() returns (uint r) { r = a({a: 1, c: 2}); }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function a(uint a, uint b) returns (uint r) { + r = a + b; + } + function b() returns (uint r) { + r = a({a: 1, c: 2}); + } + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1371,9 +1499,9 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter) { char const* text = R"( contract test { - function f(uint){ + function f(uint) { } } - })"; + )"; CHECK_SUCCESS(text); } @@ -1381,9 +1509,9 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter) { char const* text = R"( contract test { - function f() returns(bool){ + function f() returns(bool) { } } - })"; + )"; CHECK_SUCCESS(text); } @@ -1391,10 +1519,11 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one) { char const* text = R"( contract test { - function f(uint, uint k) returns(uint ret_k){ + function f(uint, uint k) returns(uint ret_k) { return k; + } } - })"; + )"; CHECK_SUCCESS(text); } @@ -1402,16 +1531,21 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter_with_named_one) { char const* text = R"( contract test { - function f() returns(uint ret_k, uint){ + function f() returns(uint ret_k, uint) { return 5; + } } - })"; + )"; CHECK_ERROR(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(disallow_declaration_of_void_type) { - char const* sourceCode = "contract c { function f() { var (x) = f(); } }"; + char const* sourceCode = R"( + contract c { + function f() { var (x) = f(); } + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1419,22 +1553,22 @@ BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units) { char const* sourceCodeFine = R"( contract c { - function c () - { - a = 115792089237316195423570985008687907853269984665640564039458; + function c () { + a = 115792089237316195423570985008687907853269984665640564039458; } uint256 a; - })"; + } + )"; ETH_TEST_CHECK_NO_THROW(parseAndAnalyse(sourceCodeFine), "Parsing and Resolving names failed"); char const* sourceCode = R"( contract c { - function c () - { + function c () { a = 115792089237316195423570985008687907853269984665640564039458 ether; } uint256 a; - })"; + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1443,21 +1577,22 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big) char const* sourceCode = R"( contract test { function f() returns(uint d) { return 2 ** 10000000000; } - })"; + } + )"; CHECK_ERROR(sourceCode, TypeError, ""); } BOOST_AUTO_TEST_CASE(enum_member_access) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - choices = ActionChoices.GoStraight; - } - ActionChoices choices; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() + { + choices = ActionChoices.GoStraight; } + ActionChoices choices; + } )"; CHECK_SUCCESS(text); } @@ -1465,14 +1600,14 @@ BOOST_AUTO_TEST_CASE(enum_member_access) BOOST_AUTO_TEST_CASE(enum_member_access_accross_contracts) { char const* text = R"( - contract Interface { - enum MyEnum { One, Two } - } - contract Impl { - function test() returns (Interface.MyEnum) { - return Interface.MyEnum.One; - } + contract Interface { + enum MyEnum { One, Two } + } + contract Impl { + function test() returns (Interface.MyEnum) { + return Interface.MyEnum.One; } + } )"; CHECK_SUCCESS(text); } @@ -1480,14 +1615,13 @@ BOOST_AUTO_TEST_CASE(enum_member_access_accross_contracts) BOOST_AUTO_TEST_CASE(enum_invalid_member_access) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - choices = ActionChoices.RunAroundWavingYourHands; - } - ActionChoices choices; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + choices = ActionChoices.RunAroundWavingYourHands; } + ActionChoices choices; + } )"; CHECK_ERROR(text, TypeError, ""); } @@ -1495,14 +1629,13 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access) BOOST_AUTO_TEST_CASE(enum_invalid_direct_member_access) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - choices = Sit; - } - ActionChoices choices; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + choices = Sit; } + ActionChoices choices; + } )"; CHECK_ERROR(text, DeclarationError, ""); } @@ -1510,16 +1643,15 @@ BOOST_AUTO_TEST_CASE(enum_invalid_direct_member_access) BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - a = uint256(ActionChoices.GoStraight); - b = uint64(ActionChoices.Sit); - } - uint256 a; - uint64 b; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + a = uint256(ActionChoices.GoStraight); + b = uint64(ActionChoices.Sit); } + uint256 a; + uint64 b; + } )"; CHECK_SUCCESS(text); } @@ -1527,33 +1659,43 @@ BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay) BOOST_AUTO_TEST_CASE(int_to_enum_explicit_conversion_is_okay) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - a = 2; - b = ActionChoices(a); - } - uint256 a; - ActionChoices b; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + a = 2; + b = ActionChoices(a); } + uint256 a; + ActionChoices b; + } )"; CHECK_SUCCESS(text); } -BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay) +BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay_256) { char const* text = R"( - contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test() - { - a = ActionChoices.GoStraight; - b = ActionChoices.Sit; - } - uint256 a; - uint64 b; + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + a = ActionChoices.GoStraight; + } + uint256 a; + } + )"; + CHECK_ERROR(text, TypeError, ""); +} + +BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay_64) +{ + char const* text = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() { + b = ActionChoices.Sit; } + uint64 b; + } )"; CHECK_ERROR(text, TypeError, ""); } @@ -1564,8 +1706,7 @@ BOOST_AUTO_TEST_CASE(enum_to_enum_conversion_is_not_okay) contract test { enum Paper { Up, Down, Left, Right } enum Ground { North, South, West, East } - function test() - { + function test() { Ground(Paper.Up); } } @@ -1609,7 +1750,7 @@ BOOST_AUTO_TEST_CASE(private_visibility) contract derived is base { function g() { f(); } } - )"; + )"; CHECK_ERROR(sourceCode, DeclarationError, ""); } @@ -1622,7 +1763,7 @@ BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access) contract derived is base { function g() { base.f(); } } - )"; + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1633,7 +1774,7 @@ BOOST_AUTO_TEST_CASE(external_visibility) function f() external {} function g() { f(); } } - )"; + )"; CHECK_ERROR(sourceCode, DeclarationError, ""); } @@ -1646,7 +1787,7 @@ BOOST_AUTO_TEST_CASE(external_base_visibility) contract derived is base { function g() { base.f(); } } - )"; + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1656,7 +1797,7 @@ BOOST_AUTO_TEST_CASE(external_argument_assign) contract c { function f(uint a) external { a = 1; } } - )"; + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1666,7 +1807,7 @@ BOOST_AUTO_TEST_CASE(external_argument_increment) contract c { function f(uint a) external { a++; } } - )"; + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1676,7 +1817,7 @@ BOOST_AUTO_TEST_CASE(external_argument_delete) contract c { function f(uint a) external { delete a; } } - )"; + )"; CHECK_ERROR(sourceCode, TypeError, ""); } @@ -1689,7 +1830,7 @@ BOOST_AUTO_TEST_CASE(test_for_bug_override_function_with_bytearray_type) contract Bike is Vehicle { function f(bytes _a) external returns (uint256 r) {r = 42;} } - )"; + )"; ETH_TEST_CHECK_NO_THROW(parseAndAnalyse(sourceCode), "Parsing and Name Resolving failed"); } @@ -1698,7 +1839,8 @@ BOOST_AUTO_TEST_CASE(array_with_nonconstant_length) char const* text = R"( contract c { function f(uint a) { uint8[a] x; } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1709,7 +1851,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types1) bytes a; uint[] b; function f() { b = a; } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1720,7 +1863,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types2) uint32[] a; uint8[] b; function f() { b = a; } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1731,7 +1875,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_conversion_possible) uint32[] a; uint8[] b; function f() { a = b; } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1742,7 +1887,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_static_dynamic) uint32[] a; uint8[80] b; function f() { a = b; } - })"; + } + )"; CHECK_SUCCESS(text); } @@ -1753,7 +1899,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static) uint[] a; uint[80] b; function f() { b = a; } - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1762,7 +1909,8 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int) char const* text = R"( contract c { uint8 a = 1000; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1771,7 +1919,8 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string) char const* text = R"( contract c { uint a = "abc"; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1887,7 +2036,8 @@ BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1) contract c { bytes arr; function f() { byte a = arr[0];} - })"; + } + )"; ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Type resolving failed"); } @@ -1897,7 +2047,8 @@ BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable) contract Foo { function changeIt() { x = 9; } uint constant x = 56; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1906,8 +2057,10 @@ BOOST_AUTO_TEST_CASE(complex_const_variable) //for now constant specifier is valid only for uint bytesXX and enums char const* text = R"( contract Foo { - mapping(uint => bool) constant mapVar; - })"; + mapping(uint => bool) x; + mapping(uint => bool) constant mapVar = x; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -1916,7 +2069,8 @@ BOOST_AUTO_TEST_CASE(uninitialized_const_variable) char const* text = R"( contract Foo { uint constant y; - })"; + } + )"; CHECK_ERROR(text, TypeError, ""); } @@ -2009,12 +2163,12 @@ BOOST_AUTO_TEST_CASE(multiple_constructors) BOOST_AUTO_TEST_CASE(equal_overload) { char const* sourceCode = R"( - contract test { + contract C { function test(uint a) returns (uint b) { } function test(uint a) external {} } )"; - CHECK_ERROR(sourceCode, DeclarationError, ""); + CHECK_ERROR_ALLOW_MULTI(sourceCode, DeclarationError, ""); } BOOST_AUTO_TEST_CASE(uninitialized_var) @@ -3165,7 +3319,7 @@ BOOST_AUTO_TEST_CASE(left_value_in_conditional_expression_not_supported_yet) } } )"; - CHECK_ERROR(text, TypeError, ""); + CHECK_ERROR_ALLOW_MULTI(text, TypeError, ""); } BOOST_AUTO_TEST_CASE(conditional_expression_with_different_struct) @@ -3179,8 +3333,8 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_different_struct) uint x; } function f() { - s1 x; - s2 y; + s1 memory x; + s2 memory y; true ? x : y; } } @@ -3661,7 +3815,7 @@ BOOST_AUTO_TEST_CASE(fixed_to_bytes_implicit_conversion) char const* text = R"( contract test { function f() { - fixed a = 3.2; + fixed a = 3.25; bytes32 c = a; } } @@ -3751,14 +3905,47 @@ BOOST_AUTO_TEST_CASE(rational_to_fixed_literal_expression) CHECK_SUCCESS(text); } -BOOST_AUTO_TEST_CASE(rational_as_exponent_value) +BOOST_AUTO_TEST_CASE(rational_as_exponent_value_neg_decimal) { char const* text = R"( contract test { function f() { fixed g = 2 ** -2.2; + } + } + )"; + BOOST_CHECK(!success(text)); +} + +BOOST_AUTO_TEST_CASE(rational_as_exponent_value_pos_decimal) +{ + char const* text = R"( + contract test { + function f() { ufixed b = 3 ** 2.5; + } + } + )"; + BOOST_CHECK(!success(text)); +} + +BOOST_AUTO_TEST_CASE(rational_as_exponent_half) +{ + char const* text = R"( + contract test { + function f() { ufixed24x24 b = 2 ** (1/2); + } + } + )"; + BOOST_CHECK(!success(text)); +} + +BOOST_AUTO_TEST_CASE(rational_as_exponent_value_neg_quarter) +{ + char const* text = R"( + contract test { + function f() { fixed40x40 c = 42 ** (-1/4); } } @@ -3766,15 +3953,48 @@ BOOST_AUTO_TEST_CASE(rational_as_exponent_value) BOOST_CHECK(!success(text)); } -BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents) +BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_15) { char const* text = R"( contract test { function f() { ufixed a = 3 ** ufixed(1.5); + } + } + )"; + BOOST_CHECK(!success(text)); +} + +BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_half) +{ + char const* text = R"( + contract test { + function f() { ufixed b = 2 ** ufixed(1/2); + } + } + )"; + BOOST_CHECK(!success(text)); +} + +BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_neg) +{ + char const* text = R"( + contract test { + function f() { fixed c = 42 ** fixed(-1/4); - fixed d = 16 ** fixed(-0.33); + } + } + )"; + BOOST_CHECK(!success(text)); +} + +BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_neg_decimal) +{ + char const* text = R"( + contract test { + function f() { + fixed d = 16 ** fixed(-0.5); } } )"; @@ -3824,7 +4044,7 @@ BOOST_AUTO_TEST_CASE(rational_bitnot_unary_operation) char const* text = R"( contract test { function f() { - fixed a = ~3.56; + fixed a = ~3.5; } } )"; @@ -3836,7 +4056,7 @@ BOOST_AUTO_TEST_CASE(rational_bitor_binary_operation) char const* text = R"( contract test { function f() { - fixed a = 1.56 | 3; + fixed a = 1.5 | 3; } } )"; @@ -3848,7 +4068,7 @@ BOOST_AUTO_TEST_CASE(rational_bitxor_binary_operation) char const* text = R"( contract test { function f() { - fixed a = 1.56 ^ 3; + fixed a = 1.75 ^ 3; } } )"; @@ -3860,7 +4080,7 @@ BOOST_AUTO_TEST_CASE(rational_bitand_binary_operation) char const* text = R"( contract test { function f() { - fixed a = 1.56 & 3; + fixed a = 1.75 & 3; } } )"; @@ -4161,7 +4381,7 @@ BOOST_AUTO_TEST_CASE(invalid_array_as_statement) char const* text = R"( contract test { struct S { uint x; } - function test(uint k) { S[k]; } + function test(uint k) { S[k]; } } )"; CHECK_ERROR(text, TypeError, ""); @@ -4517,11 +4737,12 @@ BOOST_AUTO_TEST_CASE(inline_assembly_storage) function f() { assembly { x := 2 + pop } } } )"; - CHECK_ERROR(text, DeclarationError, ""); + CHECK_ERROR(text, DeclarationError, "not found, not unique or not lvalue."); } BOOST_AUTO_TEST_CASE(inline_assembly_storage_in_modifiers) @@ -4532,6 +4753,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_storage_in_modifiers) modifier m { assembly { x := 2 + pop } _; } diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp index ef69e85c..e32264c4 100644 --- a/test/libsolidity/SolidityNatspecJSON.cpp +++ b/test/libsolidity/SolidityNatspecJSON.cpp @@ -76,10 +76,12 @@ BOOST_FIXTURE_TEST_SUITE(SolidityNatspecJSON, DocumentationChecker) BOOST_AUTO_TEST_CASE(user_basic_test) { - char const* sourceCode = "contract test {\n" - " /// @notice Multiplies `a` by 7\n" - " function mul(uint a) returns(uint d) { return a * 7; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @notice Multiplies `a` by 7 + function mul(uint a) returns(uint d) { return a * 7; } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -91,11 +93,13 @@ BOOST_AUTO_TEST_CASE(user_basic_test) BOOST_AUTO_TEST_CASE(dev_and_user_basic_test) { - char const* sourceCode = "contract test {\n" - " /// @notice Multiplies `a` by 7\n" - " /// @dev Multiplies a number by 7\n" - " function mul(uint a) returns(uint d) { return a * 7; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @notice Multiplies `a` by 7 + /// @dev Multiplies a number by 7 + function mul(uint a) returns(uint d) { return a * 7; } + } + )"; char const* devNatspec = "{" "\"methods\":{" @@ -116,14 +120,15 @@ BOOST_AUTO_TEST_CASE(dev_and_user_basic_test) BOOST_AUTO_TEST_CASE(user_multiline_comment) { - char const* sourceCode = "contract test {\n" - " /// @notice Multiplies `a` by 7\n" - " /// and then adds `b`\n" - " function mul_and_add(uint a, uint256 b) returns(uint256 d)\n" - " {\n" - " return (a * 7) + b;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @notice Multiplies `a` by 7 + /// and then adds `b` + function mul_and_add(uint a, uint256 b) returns(uint256 d) { + return (a * 7) + b; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -135,24 +140,24 @@ BOOST_AUTO_TEST_CASE(user_multiline_comment) BOOST_AUTO_TEST_CASE(user_multiple_functions) { - char const* sourceCode = "contract test {\n" - " /// @notice Multiplies `a` by 7 and then adds `b`\n" - " function mul_and_add(uint a, uint256 b) returns(uint256 d)\n" - " {\n" - " return (a * 7) + b;\n" - " }\n" - "\n" - " /// @notice Divides `input` by `div`\n" - " function divide(uint input, uint div) returns(uint d)\n" - " {\n" - " return input / div;\n" - " }\n" - " /// @notice Subtracts 3 from `input`\n" - " function sub(int input) returns(int d)\n" - " {\n" - " return input - 3;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @notice Multiplies `a` by 7 and then adds `b` + function mul_and_add(uint a, uint256 b) returns(uint256 d) { + return (a * 7) + b; + } + + /// @notice Divides `input` by `div` + function divide(uint input, uint div) returns(uint d) { + return input / div; + } + + /// @notice Subtracts 3 from `input` + function sub(int input) returns(int d) { + return input - 3; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -166,8 +171,9 @@ BOOST_AUTO_TEST_CASE(user_multiple_functions) BOOST_AUTO_TEST_CASE(user_empty_contract) { - char const* sourceCode = "contract test {\n" - "}\n"; + char const* sourceCode = R"( + contract test { } + )"; char const* natspec = "{\"methods\":{} }"; @@ -176,13 +182,16 @@ BOOST_AUTO_TEST_CASE(user_empty_contract) BOOST_AUTO_TEST_CASE(dev_and_user_no_doc) { - char const* sourceCode = "contract test {\n" - " function mul(uint a) returns(uint d) { return a * 7; }\n" - " function sub(int input) returns(int d)\n" - " {\n" - " return input - 3;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + function mul(uint a) returns(uint d) { + return a * 7; + } + function sub(int input) returns(int d) { + return input - 3; + } + } + )"; char const* devNatspec = "{\"methods\":{}}"; char const* userNatspec = "{\"methods\":{}}"; @@ -193,13 +202,15 @@ BOOST_AUTO_TEST_CASE(dev_and_user_no_doc) BOOST_AUTO_TEST_CASE(dev_desc_after_nl) { - char const* sourceCode = "contract test {\n" - " /// @dev\n" - " /// Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter\n" - " /// @param second Documentation for the second parameter\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev + /// Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -217,12 +228,14 @@ BOOST_AUTO_TEST_CASE(dev_desc_after_nl) BOOST_AUTO_TEST_CASE(dev_multiple_params) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter\n" - " /// @param second Documentation for the second parameter\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -240,13 +253,15 @@ BOOST_AUTO_TEST_CASE(dev_multiple_params) BOOST_AUTO_TEST_CASE(dev_mutiline_param_description) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter starts here.\n" - " /// Since it's a really complicated parameter we need 2 lines\n" - " /// @param second Documentation for the second parameter\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -264,26 +279,27 @@ BOOST_AUTO_TEST_CASE(dev_mutiline_param_description) BOOST_AUTO_TEST_CASE(dev_multiple_functions) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter\n" - " /// @param second Documentation for the second parameter\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - " \n" - " /// @dev Divides 2 numbers\n" - " /// @param input Documentation for the input parameter\n" - " /// @param div Documentation for the div parameter\n" - " function divide(uint input, uint div) returns(uint d)\n" - " {\n" - " return input / div;\n" - " }\n" - " /// @dev Subtracts 3 from `input`\n" - " /// @param input Documentation for the input parameter\n" - " function sub(int input) returns(int d)\n" - " {\n" - " return input - 3;\n" - " }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + function mul(uint a, uint second) returns(uint d) { + return a * 7 + second; + } + /// @dev Divides 2 numbers + /// @param input Documentation for the input parameter + /// @param div Documentation for the div parameter + function divide(uint input, uint div) returns(uint d) { + return input / div; + } + /// @dev Subtracts 3 from `input` + /// @param input Documentation for the input parameter + function sub(int input) returns(int d) { + return input - 3; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -314,14 +330,16 @@ BOOST_AUTO_TEST_CASE(dev_multiple_functions) BOOST_AUTO_TEST_CASE(dev_return) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter starts here.\n" - " /// Since it's a really complicated parameter we need 2 lines\n" - " /// @param second Documentation for the second parameter\n" - " /// @return The result of the multiplication\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return The result of the multiplication + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -339,15 +357,19 @@ BOOST_AUTO_TEST_CASE(dev_return) } BOOST_AUTO_TEST_CASE(dev_return_desc_after_nl) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter starts here.\n" - " /// Since it's a really complicated parameter we need 2 lines\n" - " /// @param second Documentation for the second parameter\n" - " /// @return\n" - " /// The result of the multiplication\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return + /// The result of the multiplication + function mul(uint a, uint second) returns(uint d) { + return a * 7 + second; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -367,15 +389,19 @@ BOOST_AUTO_TEST_CASE(dev_return_desc_after_nl) BOOST_AUTO_TEST_CASE(dev_multiline_return) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter starts here.\n" - " /// Since it's a really complicated parameter we need 2 lines\n" - " /// @param second Documentation for the second parameter\n" - " /// @return The result of the multiplication\n" - " /// and cookies with nutella\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return The result of the multiplication + /// and cookies with nutella + function mul(uint a, uint second) returns(uint d) { + return a * 7 + second; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -394,17 +420,21 @@ BOOST_AUTO_TEST_CASE(dev_multiline_return) BOOST_AUTO_TEST_CASE(dev_multiline_comment) { - char const* sourceCode = "contract test {\n" - " /**\n" - " * @dev Multiplies a number by 7 and adds second parameter\n" - " * @param a Documentation for the first parameter starts here.\n" - " * Since it's a really complicated parameter we need 2 lines\n" - " * @param second Documentation for the second parameter\n" - " * @return The result of the multiplication\n" - " * and cookies with nutella\n" - " */" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /** + * @dev Multiplies a number by 7 and adds second parameter + * @param a Documentation for the first parameter starts here. + * Since it's a really complicated parameter we need 2 lines + * @param second Documentation for the second parameter + * @return The result of the multiplication + * and cookies with nutella + */ + function mul(uint a, uint second) returns(uint d) { + return a * 7 + second; + } + } + )"; char const* natspec = "{" "\"methods\":{" @@ -423,10 +453,12 @@ BOOST_AUTO_TEST_CASE(dev_multiline_comment) BOOST_AUTO_TEST_CASE(dev_contract_no_doc) { - char const* sourceCode = "contract test {\n" - " /// @dev Mul function\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Mul function + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" " \"methods\":{" @@ -441,12 +473,14 @@ BOOST_AUTO_TEST_CASE(dev_contract_no_doc) BOOST_AUTO_TEST_CASE(dev_contract_doc) { - char const* sourceCode = " /// @author Lefteris\n" - " /// @title Just a test contract\n" - "contract test {\n" - " /// @dev Mul function\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + /// @author Lefteris + /// @title Just a test contract + contract test { + /// @dev Mul function + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" " \"author\": \"Lefteris\"," @@ -463,13 +497,15 @@ BOOST_AUTO_TEST_CASE(dev_contract_doc) BOOST_AUTO_TEST_CASE(dev_author_at_function) { - char const* sourceCode = " /// @author Lefteris\n" - " /// @title Just a test contract\n" - "contract test {\n" - " /// @dev Mul function\n" - " /// @author John Doe\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + /// @author Lefteris + /// @title Just a test contract + contract test { + /// @dev Mul function + /// @author John Doe + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; char const* natspec = "{" " \"author\": \"Lefteris\"," @@ -549,25 +585,29 @@ BOOST_AUTO_TEST_CASE(empty_comment) BOOST_AUTO_TEST_CASE(dev_title_at_function_error) { - char const* sourceCode = " /// @author Lefteris\n" - " /// @title Just a test contract\n" - "contract test {\n" - " /// @dev Mul function\n" - " /// @title I really should not be here\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + /// @author Lefteris + /// @title Just a test contract + contract test { + /// @dev Mul function + /// @title I really should not be here + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; expectNatspecError(sourceCode); } -BOOST_AUTO_TEST_CASE(dev_documenting_nonexistant_param) +BOOST_AUTO_TEST_CASE(dev_documenting_nonexistent_param) { - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter\n" - " /// @param not_existing Documentation for the second parameter\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" - "}\n"; + char const* sourceCode = R"( + contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param not_existing Documentation for the second parameter + function mul(uint a, uint second) returns(uint d) { return a * 7 + second; } + } + )"; expectNatspecError(sourceCode); } diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 3c1f465a..2e2e0c6c 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -50,6 +50,25 @@ class OptimizerTestFramework: public SolidityExecutionFramework { public: OptimizerTestFramework() { } + + bytes const& compileAndRunWithOptimizer( + std::string const& _sourceCode, + u256 const& _value = 0, + std::string const& _contractName = "", + bool const _optimize = true, + unsigned const _optimizeRuns = 200 + ) + { + bool const c_optimize = m_optimize; + unsigned const c_optimizeRuns = m_optimizeRuns; + m_optimize = _optimize; + m_optimizeRuns = _optimizeRuns; + bytes const& ret = compileAndRun(_sourceCode, _value, _contractName); + m_optimize = c_optimize; + m_optimizeRuns = c_optimizeRuns; + return ret; + } + /// Compiles the source code with and without optimizing. void compileBothVersions( std::string const& _sourceCode, @@ -57,22 +76,16 @@ public: std::string const& _contractName = "" ) { - m_optimize = false; - bytes nonOptimizedBytecode = compileAndRun(_sourceCode, _value, _contractName); + bytes nonOptimizedBytecode = compileAndRunWithOptimizer(_sourceCode, _value, _contractName, false); m_nonOptimizedContract = m_contractAddress; - m_optimize = true; - bytes optimizedBytecode = compileAndRun(_sourceCode, _value, _contractName); - size_t nonOptimizedSize = 0; - solidity::eachInstruction(nonOptimizedBytecode, [&](Instruction, u256 const&) { - nonOptimizedSize++; - }); - size_t optimizedSize = 0; - solidity::eachInstruction(optimizedBytecode, [&](Instruction, u256 const&) { - optimizedSize++; - }); + bytes optimizedBytecode = compileAndRunWithOptimizer(_sourceCode, _value, _contractName, true); + size_t nonOptimizedSize = numInstructions(nonOptimizedBytecode); + size_t optimizedSize = numInstructions(optimizedBytecode); BOOST_CHECK_MESSAGE( - nonOptimizedSize > optimizedSize, - "Optimizer did not reduce bytecode size." + optimizedSize < nonOptimizedSize, + string("Optimizer did not reduce bytecode size. Non-optimized size: ") + + std::to_string(nonOptimizedSize) + " - optimized size: " + + std::to_string(optimizedSize) ); m_optimizedContract = m_contractAddress; } @@ -156,6 +169,22 @@ public: } protected: + /// @returns the number of intructions in the given bytecode, not taking the metadata hash + /// into account. + size_t numInstructions(bytes const& _bytecode) + { + BOOST_REQUIRE(_bytecode.size() > 5); + size_t metadataSize = (_bytecode[_bytecode.size() - 2] << 8) + _bytecode[_bytecode.size() - 1]; + BOOST_REQUIRE_MESSAGE(metadataSize == 0x29, "Invalid metadata size"); + BOOST_REQUIRE(_bytecode.size() >= metadataSize + 2); + bytes realCode = bytes(_bytecode.begin(), _bytecode.end() - metadataSize - 2); + size_t instructions = 0; + solidity::eachInstruction(realCode, [&](Instruction, u256 const&) { + instructions++; + }); + return instructions; + } + Address m_optimizedContract; Address m_nonOptimizedContract; }; @@ -315,8 +344,7 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches) compareVersions("f(uint256,bytes32)", 8, "def"); compareVersions("f(uint256,bytes32)", 10, "ghi"); - m_optimize = true; - bytes optimizedBytecode = compileAndRun(sourceCode, 0, "c"); + bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "c", true); size_t numSHA3s = 0; eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) { if (_instr == Instruction::SHA3) @@ -359,8 +387,7 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions) compileBothVersions(sourceCode); compareVersions("f(uint256,bytes32)", 7, "abc"); - m_optimize = true; - bytes optimizedBytecode = compileAndRun(sourceCode, 0, "test"); + bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "test", true); size_t numSHA3s = 0; eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) { if (_instr == Instruction::SHA3) @@ -1187,9 +1214,7 @@ BOOST_AUTO_TEST_CASE(computing_constants) compareVersions("set()"); compareVersions("get()"); - m_optimize = true; - m_optimizeRuns = 1; - bytes optimizedBytecode = compileAndRun(sourceCode, 0, "c"); + bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "c", true, 1); bytes complicatedConstant = toBigEndian(u256("0x817416927846239487123469187231298734162934871263941234127518276")); unsigned occurrences = 0; for (auto iter = optimizedBytecode.cbegin(); iter < optimizedBytecode.cend(); ++occurrences) diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index a3217f08..a3bfab75 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -26,6 +26,7 @@ #include <libsolidity/parsing/Parser.h> #include <libsolidity/interface/Exceptions.h> #include "../TestHelper.h" +#include "ErrorCheck.h" using namespace std; @@ -71,6 +72,22 @@ bool successParse(std::string const& _source) return true; } +Error getError(std::string const& _source) +{ + ErrorList errors; + try + { + parseText(_source, errors); + } + catch (FatalError const& /*_exception*/) + { + // no-op + } + Error const* error = Error::containsErrorOfType(errors, Error::Type::ParserError); + BOOST_REQUIRE(error); + return *error; +} + void checkFunctionNatspec( FunctionDefinition const* _function, std::string const& _expectedDoc @@ -83,78 +100,102 @@ void checkFunctionNatspec( } +#define CHECK_PARSE_ERROR(source, substring) \ +do \ +{\ + Error err = getError((source)); \ + BOOST_CHECK(searchErrorMessage(err, (substring))); \ +}\ +while(0) + BOOST_AUTO_TEST_SUITE(SolidityParser) BOOST_AUTO_TEST_CASE(smoke_test) { - char const* text = "contract test {\n" - " uint256 stateVariable1;\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVariable1; + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(missing_variable_name_in_declaration) { - char const* text = "contract test {\n" - " uint256 ;\n" - "}\n"; - BOOST_CHECK(!successParse(text)); + char const* text = R"( + contract test { + uint256 ; + } + )"; + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(empty_function) { - char const* text = "contract test {\n" - " uint256 stateVar;\n" - " function functionName(bytes20 arg1, address addr) constant\n" - " returns (int id)\n" - " { }\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVar; + function functionName(bytes20 arg1, address addr) constant + returns (int id) + { } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(no_function_params) { - char const* text = "contract test {\n" - " uint256 stateVar;\n" - " function functionName() {}\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVar; + function functionName() {} + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(single_function_param) { - char const* text = "contract test {\n" - " uint256 stateVar;\n" - " function functionName(bytes32 input) returns (bytes32 out) {}\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVar; + function functionName(bytes32 input) returns (bytes32 out) {} + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(function_no_body) { - char const* text = "contract test {\n" - " function functionName(bytes32 input) returns (bytes32 out);\n" - "}\n"; + char const* text = R"( + contract test { + function functionName(bytes32 input) returns (bytes32 out); + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(missing_parameter_name_in_named_args) { - char const* text = "contract test {\n" - " function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n" - " function b() returns (uint r) { r = a({: 1, : 2, : 3}); }\n" - "}\n"; - BOOST_CHECK(!successParse(text)); + char const* text = R"( + contract test { + function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; } + function b() returns (uint r) { r = a({: 1, : 2, : 3}); } + } + )"; + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(missing_argument_in_named_args) { - char const* text = "contract test {\n" - " function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n" - " function b() returns (uint r) { r = a({a: , b: , c: }); }\n" - "}\n"; - BOOST_CHECK(!successParse(text)); + char const* text = R"( + contract test { + function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; } + function b() returns (uint r) { r = a({a: , b: , c: }); } + } + )"; + CHECK_PARSE_ERROR(text, "Expected primary expression"); } BOOST_AUTO_TEST_CASE(two_exact_functions) @@ -184,11 +225,13 @@ BOOST_AUTO_TEST_CASE(overloaded_functions) BOOST_AUTO_TEST_CASE(function_natspec_documentation) { - char const* text = "contract test {\n" - " uint256 stateVar;\n" - " /// This is a test function\n" - " function functionName(bytes32 input) returns (bytes32 out) {}\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVar; + /// This is a test function + function functionName(bytes32 input) returns (bytes32 out) {} + } + )"; BOOST_CHECK(successParse(text)); ErrorList errors; ASTPointer<ContractDefinition> contract = parseText(text, errors); @@ -202,11 +245,13 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation) BOOST_AUTO_TEST_CASE(function_normal_comments) { FunctionDefinition const* function = nullptr; - char const* text = "contract test {\n" - " uint256 stateVar;\n" - " // We won't see this comment\n" - " function functionName(bytes32 input) returns (bytes32 out) {}\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVar; + // We won't see this comment + function functionName(bytes32 input) returns (bytes32 out) {} + } + )"; BOOST_CHECK(successParse(text)); ErrorList errors; ASTPointer<ContractDefinition> contract = parseText(text, errors); @@ -219,17 +264,19 @@ BOOST_AUTO_TEST_CASE(function_normal_comments) BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation) { FunctionDefinition const* function = nullptr; - char const* text = "contract test {\n" - " uint256 stateVar;\n" - " /// This is test function 1\n" - " function functionName1(bytes32 input) returns (bytes32 out) {}\n" - " /// This is test function 2\n" - " function functionName2(bytes32 input) returns (bytes32 out) {}\n" - " // nothing to see here\n" - " function functionName3(bytes32 input) returns (bytes32 out) {}\n" - " /// This is test function 4\n" - " function functionName4(bytes32 input) returns (bytes32 out) {}\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVar; + /// This is test function 1 + function functionName1(bytes32 input) returns (bytes32 out) {} + /// This is test function 2 + function functionName2(bytes32 input) returns (bytes32 out) {} + // nothing to see here + function functionName3(bytes32 input) returns (bytes32 out) {} + /// This is test function 4 + function functionName4(bytes32 input) returns (bytes32 out) {} + } + )"; BOOST_CHECK(successParse(text)); ErrorList errors; ASTPointer<ContractDefinition> contract = parseText(text, errors); @@ -252,12 +299,14 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation) BOOST_AUTO_TEST_CASE(multiline_function_documentation) { FunctionDefinition const* function = nullptr; - char const* text = "contract test {\n" - " uint256 stateVar;\n" - " /// This is a test function\n" - " /// and it has 2 lines\n" - " function functionName1(bytes32 input) returns (bytes32 out) {}\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVar; + /// This is a test function + /// and it has 2 lines + function functionName1(bytes32 input) returns (bytes32 out) {} + } + )"; BOOST_CHECK(successParse(text)); ErrorList errors; ASTPointer<ContractDefinition> contract = parseText(text, errors); @@ -270,19 +319,21 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation) BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body) { FunctionDefinition const* function = nullptr; - char const* text = "contract test {\n" - " /// fun1 description\n" - " function fun1(uint256 a) {\n" - " var b;\n" - " /// I should not interfere with actual natspec comments\n" - " uint256 c;\n" - " mapping(address=>bytes32) d;\n" - " bytes7 name = \"Solidity\";" - " }\n" - " /// This is a test function\n" - " /// and it has 2 lines\n" - " function fun(bytes32 input) returns (bytes32 out) {}\n" - "}\n"; + char const* text = R"( + contract test { + /// fun1 description + function fun1(uint256 a) { + var b; + /// I should not interfere with actual natspec comments + uint256 c; + mapping(address=>bytes32) d; + bytes7 name = "Solidity"; + } + /// This is a test function + /// and it has 2 lines + function fun(bytes32 input) returns (bytes32 out) {} + } + )"; BOOST_CHECK(successParse(text)); ErrorList errors; ASTPointer<ContractDefinition> contract = parseText(text, errors); @@ -299,17 +350,19 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body) BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature) { FunctionDefinition const* function = nullptr; - char const* text = "contract test {\n" - " uint256 stateVar;\n" - " function ///I am in the wrong place \n" - " fun1(uint256 a) {\n" - " var b;\n" - " /// I should not interfere with actual natspec comments\n" - " uint256 c;\n" - " mapping(address=>bytes32) d;\n" - " bytes7 name = \"Solidity\";" - " }\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVar; + function ///I am in the wrong place + fun1(uint256 a) { + var b; + /// I should not interfere with actual natspec comments + uint256 c; + mapping(address=>bytes32) d; + bytes7 name = "Solidity"; + } + } + )"; BOOST_CHECK(successParse(text)); ErrorList errors; ASTPointer<ContractDefinition> contract = parseText(text, errors); @@ -323,17 +376,19 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature) BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature) { FunctionDefinition const* function = nullptr; - char const* text = "contract test {\n" - " uint256 stateVar;\n" - " function fun1(uint256 a) {\n" - " /// I should have been above the function signature\n" - " var b;\n" - " /// I should not interfere with actual natspec comments\n" - " uint256 c;\n" - " mapping(address=>bytes32) d;\n" - " bytes7 name = \"Solidity\";" - " }\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVar; + function fun1(uint256 a) { + /// I should have been above the function signature + var b; + /// I should not interfere with actual natspec comments + uint256 c; + mapping(address=>bytes32) d; + bytes7 name = "Solidity"; + } + } + )"; BOOST_CHECK(successParse(text)); ErrorList errors; ASTPointer<ContractDefinition> contract = parseText(text, errors); @@ -346,71 +401,83 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature) BOOST_AUTO_TEST_CASE(struct_definition) { - char const* text = "contract test {\n" - " uint256 stateVar;\n" - " struct MyStructName {\n" - " address addr;\n" - " uint256 count;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + uint256 stateVar; + struct MyStructName { + address addr; + uint256 count; + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(mapping) { - char const* text = "contract test {\n" - " mapping(address => bytes32) names;\n" - "}\n"; + char const* text = R"( + contract test { + mapping(address => bytes32) names; + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(mapping_in_struct) { - char const* text = "contract test {\n" - " struct test_struct {\n" - " address addr;\n" - " uint256 count;\n" - " mapping(bytes32 => test_struct) self_reference;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct test_struct { + address addr; + uint256 count; + mapping(bytes32 => test_struct) self_reference; + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(mapping_to_mapping_in_struct) { - char const* text = "contract test {\n" - " struct test_struct {\n" - " address addr;\n" - " mapping (uint64 => mapping (bytes32 => uint)) complex_mapping;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + struct test_struct { + address addr; + mapping (uint64 => mapping (bytes32 => uint)) complex_mapping; + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(variable_definition) { - char const* text = "contract test {\n" - " function fun(uint256 a) {\n" - " var b;\n" - " uint256 c;\n" - " mapping(address=>bytes32) d;\n" - " customtype varname;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) { + var b; + uint256 c; + mapping(address=>bytes32) d; + customtype varname; + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(variable_definition_with_initialization) { - char const* text = "contract test {\n" - " function fun(uint256 a) {\n" - " var b = 2;\n" - " uint256 c = 0x87;\n" - " mapping(address=>bytes32) d;\n" - " bytes7 name = \"Solidity\";" - " customtype varname;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) { + var b = 2; + uint256 c = 0x87; + mapping(address=>bytes32) d; + bytes7 name = "Solidity"; + customtype varname; + } + } + )"; BOOST_CHECK(successParse(text)); } @@ -421,7 +488,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_function_parameter) function fun(var a) {} } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected explicit type name"); } BOOST_AUTO_TEST_CASE(variable_definition_in_mapping) @@ -433,7 +500,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_mapping) } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected elementary type name for mapping key type"); } BOOST_AUTO_TEST_CASE(variable_definition_in_function_return) @@ -445,26 +512,30 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_function_return) } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected explicit type name"); } BOOST_AUTO_TEST_CASE(operator_expression) { - char const* text = "contract test {\n" - " function fun(uint256 a) {\n" - " uint256 x = (1 + 4) || false && (1 - 12) + -9;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) { + uint256 x = (1 + 4) || false && (1 - 12) + -9; + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(complex_expression) { - char const* text = "contract test {\n" - " function fun(uint256 a) {\n" - " uint256 x = (1 + 4).member(++67)[a/=9] || true;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) { + uint256 x = (1 + 4).member(++67)[a/=9] || true; + } + } + )"; BOOST_CHECK(successParse(text)); } @@ -475,248 +546,294 @@ BOOST_AUTO_TEST_CASE(exp_expression) function fun(uint256 a) { uint256 x = 3 ** a; } - })"; + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(while_loop) { - char const* text = "contract test {\n" - " function fun(uint256 a) {\n" - " while (true) { uint256 x = 1; break; continue; } x = 9;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) { + while (true) { uint256 x = 1; break; continue; } x = 9; + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(for_loop_vardef_initexpr) { - char const* text = "contract test {\n" - " function fun(uint256 a) {\n" - " for (uint256 i = 0; i < 10; i++)\n" - " { uint256 x = i; break; continue; }\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) { + for (uint256 i = 0; i < 10; i++) { + uint256 x = i; break; continue; + } + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr) { - char const* text = "contract test {\n" - " function fun(uint256 a) {\n" - " uint256 i =0;\n" - " for (i = 0; i < 10; i++)\n" - " { uint256 x = i; break; continue; }\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) { + uint256 i =0; + for (i = 0; i < 10; i++) { + uint256 x = i; break; continue; + } + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr) { - char const* text = "contract test {\n" - " function fun(uint256 a) {\n" - " uint256 i =0;\n" - " for (;;)\n" - " { uint256 x = i; break; continue; }\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) { + uint256 i =0; + for (;;) { + uint256 x = i; break; continue; + } + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body) { - char const* text = "contract test {\n" - " function fun(uint256 a) {\n" - " uint256 i =0;\n" - " for (i = 0; i < 10; i++)\n" - " continue;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) { + uint256 i = 0; + for (i = 0; i < 10; i++) + continue; + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(if_statement) { - char const* text = "contract test {\n" - " function fun(uint256 a) {\n" - " if (a >= 8) { return 2; } else { var b = 7; }\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) { + if (a >= 8) { return 2; } else { var b = 7; } + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(else_if_statement) { - char const* text = "contract test {\n" - " function fun(uint256 a) returns (address b) {\n" - " if (a < 0) b = 0x67; else if (a == 0) b = 0x12; else b = 0x78;\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun(uint256 a) returns (address b) { + if (a < 0) b = 0x67; else if (a == 0) b = 0x12; else b = 0x78; + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(statement_starting_with_type_conversion) { - char const* text = "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " uint64[7](3);\n" - " uint64[](3);\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + uint64(2); + uint64[7](3); + uint64[](3); + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(type_conversion_to_dynamic_array) { - char const* text = "contract test {\n" - " function fun() {\n" - " var x = uint64[](3);\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + var x = uint64[](3); + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(import_directive) { - char const* text = "import \"abc\";\n" - "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n"; + char const* text = R"( + import "abc"; + contract test { + function fun() { + uint64(2); + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(multiple_contracts) { - char const* text = "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n" - "contract test2 {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n"; + char const* text = R"( + contract test { + function fun() { + uint64(2); + } + } + contract test2 { + function fun() { + uint64(2); + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports) { - char const* text = "import \"abc\";\n" - "contract test {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n" - "import \"def\";\n" - "contract test2 {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n" - "import \"ghi\";\n"; + char const* text = R"( + import "abc"; + contract test { + function fun() { + uint64(2); + } + } + import "def"; + contract test2 { + function fun() { + uint64(2); + } + } + import "ghi"; + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(contract_inheritance) { - char const* text = "contract base {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n" - "contract derived is base {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n"; + char const* text = R"( + contract base { + function fun() { + uint64(2); + } + } + contract derived is base { + function fun() { + uint64(2); + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(contract_multiple_inheritance) { - char const* text = "contract base {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n" - "contract derived is base, nonExisting {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n"; + char const* text = R"( + contract base { + function fun() { + uint64(2); + } + } + contract derived is base, nonExisting { + function fun() { + uint64(2); + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(contract_multiple_inheritance_with_arguments) { - char const* text = "contract base {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n" - "contract derived is base(2), nonExisting(\"abc\", \"def\", base.fun()) {\n" - " function fun() {\n" - " uint64(2);\n" - " }\n" - "}\n"; + char const* text = R"( + contract base { + function fun() { + uint64(2); + } + } + contract derived is base(2), nonExisting("abc", "def", base.fun()) { + function fun() { + uint64(2); + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(placeholder_in_function_context) { - char const* text = "contract c {\n" - " function fun() returns (uint r) {\n" - " var _ = 8;\n" - " return _ + 1;" - " }\n" - "}\n"; + char const* text = R"( + contract c { + function fun() returns (uint r) { + var _ = 8; + return _ + 1; + } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(modifier) { - char const* text = "contract c {\n" - " modifier mod { if (msg.sender == 0) _; }\n" - "}\n"; + char const* text = R"( + contract c { + modifier mod { if (msg.sender == 0) _; } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(modifier_without_semicolon) { - char const* text = "contract c {\n" - " modifier mod { if (msg.sender == 0) _ }\n" - "}\n"; - BOOST_CHECK(!successParse(text)); + char const* text = R"( + contract c { + modifier mod { if (msg.sender == 0) _ } + } + )"; + CHECK_PARSE_ERROR(text, "Expected token Semicolon got"); } BOOST_AUTO_TEST_CASE(modifier_arguments) { - char const* text = "contract c {\n" - " modifier mod(uint a) { if (msg.sender == a) _; }\n" - "}\n"; + char const* text = R"( + contract c { + modifier mod(address a) { if (msg.sender == a) _; } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(modifier_invocation) { - char const* text = "contract c {\n" - " modifier mod1(uint a) { if (msg.sender == a) _; }\n" - " modifier mod2 { if (msg.sender == 2) _; }\n" - " function f() mod1(7) mod2 { }\n" - "}\n"; + char const* text = R"( + contract c { + modifier mod1(uint a) { if (msg.sender == a) _; } + modifier mod2 { if (msg.sender == 2) _; } + function f() mod1(7) mod2 { } + } + )"; BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(fallback_function) { - char const* text = "contract c {\n" - " function() { }\n" - "}\n"; + char const* text = R"( + contract c { + function() { } + } + )"; BOOST_CHECK(successParse(text)); } @@ -769,7 +886,7 @@ BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers) contract c { uint private internal a; })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Visibility already specified"); } BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations) @@ -824,7 +941,7 @@ BOOST_AUTO_TEST_CASE(empty_enum_declaration) contract c { enum foo { } })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "enum with no members is not allowed"); } BOOST_AUTO_TEST_CASE(malformed_enum_declaration) @@ -833,7 +950,7 @@ BOOST_AUTO_TEST_CASE(malformed_enum_declaration) contract c { enum foo { WARNING,} })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected Identifier after"); } BOOST_AUTO_TEST_CASE(external_function) @@ -851,7 +968,7 @@ BOOST_AUTO_TEST_CASE(external_variable) contract c { uint external x; })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(arrays_in_storage) @@ -899,7 +1016,7 @@ BOOST_AUTO_TEST_CASE(constant_is_keyword) contract Foo { uint constant = 4; })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(var_array) @@ -908,7 +1025,7 @@ BOOST_AUTO_TEST_CASE(var_array) contract Foo { function f() { var[] a; } })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(location_specifiers_for_params) @@ -940,7 +1057,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_for_state) contract Foo { uint[] memory x; })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(location_specifiers_with_var) @@ -949,7 +1066,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_with_var) contract Foo { function f() { var memory x; } })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Location specifier needs explicit type name"); } BOOST_AUTO_TEST_CASE(empty_comment) @@ -962,6 +1079,19 @@ BOOST_AUTO_TEST_CASE(empty_comment) BOOST_CHECK(successParse(text)); } +BOOST_AUTO_TEST_CASE(comment_end_with_double_star) +{ + char const* text = R"( + contract C1 { + /** + **/ + } + contract C2 {} + )"; + BOOST_CHECK(successParse(text)); +} + + BOOST_AUTO_TEST_CASE(library_simple) { char const* text = R"( @@ -983,7 +1113,7 @@ BOOST_AUTO_TEST_CASE(local_const_variable) return local; } })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected token Semicolon"); } BOOST_AUTO_TEST_CASE(multi_variable_declaration) @@ -1102,7 +1232,7 @@ BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_lvalue) } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected expression"); } BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_without_lvalue) @@ -1115,7 +1245,7 @@ BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_without_lvalue) } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected expression"); } BOOST_AUTO_TEST_CASE(conditional_true_false_literal) @@ -1216,7 +1346,7 @@ BOOST_AUTO_TEST_CASE(no_double_radix_in_fixed_literal) fixed40x40 pi = 3.14.15; } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected token Semicolon"); } BOOST_AUTO_TEST_CASE(invalid_fixed_conversion_leading_zeroes_check) @@ -1228,7 +1358,7 @@ BOOST_AUTO_TEST_CASE(invalid_fixed_conversion_leading_zeroes_check) } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected primary expression"); } BOOST_AUTO_TEST_CASE(payable_accessor) @@ -1238,7 +1368,7 @@ BOOST_AUTO_TEST_CASE(payable_accessor) uint payable x; } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(function_type_in_expression) @@ -1271,7 +1401,7 @@ BOOST_AUTO_TEST_CASE(function_type_as_storage_variable_with_modifiers) function (uint, uint) modifier1() returns (uint) f1; } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected token LBrace"); } BOOST_AUTO_TEST_CASE(function_type_as_storage_variable_with_assignment) |