diff options
Diffstat (limited to 'test/libsolidity')
-rw-r--r-- | test/libsolidity/ASTJSON.cpp | 30 | ||||
-rw-r--r-- | test/libsolidity/InlineAssembly.cpp | 42 | ||||
-rw-r--r-- | test/libsolidity/JSONCompiler.cpp | 10 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 56 | ||||
-rw-r--r-- | test/libsolidity/SolidityOptimizer.cpp | 26 | ||||
-rw-r--r-- | test/libsolidity/SolidityParser.cpp | 11 | ||||
-rw-r--r-- | test/libsolidity/StandardCompiler.cpp | 7 |
7 files changed, 171 insertions, 11 deletions
diff --git a/test/libsolidity/ASTJSON.cpp b/test/libsolidity/ASTJSON.cpp index df7fac51..4fb4f20c 100644 --- a/test/libsolidity/ASTJSON.cpp +++ b/test/libsolidity/ASTJSON.cpp @@ -228,6 +228,36 @@ BOOST_AUTO_TEST_CASE(function_type) BOOST_CHECK_EQUAL(funType["attributes"]["visibility"], "external"); } +BOOST_AUTO_TEST_CASE(documentation) +{ + CompilerStack c; + c.addSource("a", "/**This contract is empty*/ contract C {}"); + c.addSource("b", + "/**This contract is empty" + " and has a line-breaking comment.*/" + "contract C {}" + ); + c.parseAndAnalyze(); + map<string, unsigned> sourceIndices; + sourceIndices["a"] = 0; + sourceIndices["b"] = 1; + Json::Value astJsonA = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a")); + Json::Value documentationA = astJsonA["children"][0]["attributes"]["documentation"]; + BOOST_CHECK_EQUAL(documentationA, "This contract is empty"); + Json::Value astJsonB = ASTJsonConverter(true, sourceIndices).toJson(c.ast("b")); + Json::Value documentationB = astJsonB["children"][0]["attributes"]["documentation"]; + BOOST_CHECK_EQUAL(documentationB, "This contract is empty and has a line-breaking comment."); + //same tests for non-legacy mode + astJsonA = ASTJsonConverter(false, sourceIndices).toJson(c.ast("a")); + documentationA = astJsonA["nodes"][0]["documentation"]; + BOOST_CHECK_EQUAL(documentationA, "This contract is empty"); + astJsonB = ASTJsonConverter(false, sourceIndices).toJson(c.ast("b")); + documentationB = astJsonB["nodes"][0]["documentation"]; + BOOST_CHECK_EQUAL(documentationB, "This contract is empty and has a line-breaking comment."); + +} + + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index d2d320db..aae6dacd 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -213,6 +213,16 @@ BOOST_AUTO_TEST_CASE(functional) BOOST_CHECK(successParse("{ let x := 2 add(7, mul(6, x)) mul(7, 8) add =: x }")); } +BOOST_AUTO_TEST_CASE(functional_partial) +{ + CHECK_PARSE_ERROR("{ let x := byte }", ParserError, "Expected token \"(\""); +} + +BOOST_AUTO_TEST_CASE(functional_partial_success) +{ + BOOST_CHECK(successParse("{ let x := byte(1, 2) }")); +} + BOOST_AUTO_TEST_CASE(functional_assignment) { BOOST_CHECK(successParse("{ let x := 2 x := 7 }")); @@ -258,7 +268,7 @@ BOOST_AUTO_TEST_CASE(switch_duplicate_case) BOOST_AUTO_TEST_CASE(switch_invalid_expression) { CHECK_PARSE_ERROR("{ switch {} default {} }", ParserError, "Literal, identifier or instruction expected."); - CHECK_PARSE_ERROR("{ 1 2 switch mul default {} }", ParserError, "Instructions are not supported as expressions for switch."); + CHECK_PARSE_ERROR("{ switch calldatasize default {} }", ParserError, "Instructions are not supported as expressions for switch."); } BOOST_AUTO_TEST_CASE(switch_default_before_case) @@ -542,6 +552,36 @@ BOOST_AUTO_TEST_CASE(keccak256) BOOST_CHECK(successAssemble("{ pop(sha3(0, 0)) }")); } +BOOST_AUTO_TEST_CASE(returndatasize) +{ + BOOST_CHECK(successAssemble("{ let r := returndatasize }")); +} + +BOOST_AUTO_TEST_CASE(returndatasize_functional) +{ + BOOST_CHECK(successAssemble("{ let r := returndatasize() }")); +} + +BOOST_AUTO_TEST_CASE(returndatacopy) +{ + BOOST_CHECK(successAssemble("{ 64 32 0 returndatacopy }")); +} + +BOOST_AUTO_TEST_CASE(returndatacopy_functional) +{ + BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }")); +} + +BOOST_AUTO_TEST_CASE(staticcall) +{ + BOOST_CHECK(successAssemble("{ pop(staticcall(10000, 0x123, 64, 0x10, 128, 0x10)) }")); +} + +BOOST_AUTO_TEST_CASE(create2) +{ + BOOST_CHECK(successAssemble("{ pop(create2(10, 0x123, 32, 64)) }")); +} + BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/JSONCompiler.cpp b/test/libsolidity/JSONCompiler.cpp index 6aec59ab..f5154395 100644 --- a/test/libsolidity/JSONCompiler.cpp +++ b/test/libsolidity/JSONCompiler.cpp @@ -90,11 +90,11 @@ BOOST_AUTO_TEST_CASE(basic_compilation) BOOST_CHECK(result["sources"]["fileA"].isObject()); BOOST_CHECK(result["sources"]["fileA"]["AST"].isObject()); BOOST_CHECK(dev::jsonCompactPrint(result["sources"]["fileA"]["AST"]) == - "{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}}," - "\"children\":[{\"attributes\":{\"baseContracts\":[null],\"contractDependencies\":[null]," - "\"contractKind\":\"contract\",\"fullyImplemented\":true,\"linearizedBaseContracts\":[1]," - "\"name\":\"A\",\"nodes\":[null],\"scope\":2},\"id\":1,\"name\":\"ContractDefinition\"," - "\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}"); + "{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}}," + "\"children\":[{\"attributes\":{\"baseContracts\":[null],\"contractDependencies\":[null]," + "\"contractKind\":\"contract\",\"documentation\":null,\"fullyImplemented\":true,\"linearizedBaseContracts\":[1]," + "\"name\":\"A\",\"nodes\":[null],\"scope\":2},\"id\":1,\"name\":\"ContractDefinition\"," + "\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}"); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index db5b9bf8..0b3cb481 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -193,11 +193,16 @@ CHECK_ERROR_OR_WARNING(text, type, substring, false, false) #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]. +// [checkWarning(text, substring)] asserts that the compilation down to typechecking +// emits a warning and with a message containing [substring]. #define CHECK_WARNING(text, substring) \ CHECK_ERROR_OR_WARNING(text, Warning, substring, true, false) +// [checkWarningAllowMulti(text, substring)] aserts that the compilation down to typechecking +// emits a warning and with a message containing [substring]. +#define CHECK_WARNING_ALLOW_MULTI(text, substring) \ +CHECK_ERROR_OR_WARNING(text, Warning, substring, true, true) + // [checkSuccess(text)] asserts that the compilation down to typechecking succeeds. #define CHECK_SUCCESS(text) do { BOOST_CHECK(success((text))); } while(0) @@ -2417,6 +2422,16 @@ BOOST_AUTO_TEST_CASE(invalid_utf8_explicit) CHECK_ERROR(sourceCode, TypeError, "Explicit type conversion not allowed"); } +BOOST_AUTO_TEST_CASE(large_utf8_codepoint) +{ + char const* sourceCode = R"( + contract C { + string s = "\xf0\x9f\xa6\x84"; + } + )"; + CHECK_SUCCESS(sourceCode); +} + BOOST_AUTO_TEST_CASE(string_index) { char const* sourceCode = R"( @@ -5780,6 +5795,43 @@ BOOST_AUTO_TEST_CASE(no_unused_inline_asm) CHECK_SUCCESS_NO_WARNINGS(text); } +BOOST_AUTO_TEST_CASE(callable_crash) +{ + char const* text = R"( + contract C { + struct S { uint a; bool x; } + S public s; + function C() { + 3({a: 1, x: true}); + } + } + )"; + CHECK_ERROR(text, TypeError, "Type is not callable"); +} + +BOOST_AUTO_TEST_CASE(returndatacopy_as_variable) +{ + char const* text = R"( + contract c { function f() { uint returndatasize; assembly { returndatasize }}} + )"; + CHECK_WARNING_ALLOW_MULTI(text, "Variable is shadowed in inline assembly by an instruction of the same name"); +} + +BOOST_AUTO_TEST_CASE(create2_as_variable) +{ + char const* text = R"( + contract c { function f() { uint create2; assembly { create2(0, 0, 0, 0) }}} + )"; + CHECK_WARNING_ALLOW_MULTI(text, "Variable is shadowed in inline assembly by an instruction of the same name"); +} + +BOOST_AUTO_TEST_CASE(shadowing_warning_can_be_removed) +{ + char const* text = R"( + contract C {function f() {assembly {}}} + )"; + CHECK_SUCCESS_NO_WARNINGS(text); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index bdcdacff..7afbe04e 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -1189,6 +1189,32 @@ BOOST_AUTO_TEST_CASE(clear_unreachable_code) ); } +BOOST_AUTO_TEST_CASE(peephole_double_push) +{ + AssemblyItems items{ + u256(0), + u256(0), + u256(5), + u256(5), + u256(4), + u256(5) + }; + AssemblyItems expectation{ + u256(0), + Instruction::DUP1, + u256(5), + Instruction::DUP1, + u256(4), + u256(5) + }; + PeepholeOptimiser peepOpt(items); + BOOST_REQUIRE(peepOpt.optimise()); + BOOST_CHECK_EQUAL_COLLECTIONS( + items.begin(), items.end(), + expectation.begin(), expectation.end() + ); +} + BOOST_AUTO_TEST_CASE(computing_constants) { char const* sourceCode = R"( diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index 31dfada9..27231b9b 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -199,6 +199,17 @@ BOOST_AUTO_TEST_CASE(missing_argument_in_named_args) CHECK_PARSE_ERROR(text, "Expected primary expression"); } +BOOST_AUTO_TEST_CASE(trailing_comma_in_named_args) +{ + 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: 1, b: 2, c: 3, }); } + } + )"; + CHECK_PARSE_ERROR(text, "Unexpected trailing comma"); +} + BOOST_AUTO_TEST_CASE(two_exact_functions) { char const* text = R"( diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 050ca500..35644a4d 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -201,11 +201,12 @@ BOOST_AUTO_TEST_CASE(basic_compilation) BOOST_CHECK(dev::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].asString()) == "60606040523415600b57fe5b5b60338060196000396000f30060606040525bfe00"); BOOST_CHECK(contract["evm"]["assembly"].isString()); - BOOST_CHECK(contract["evm"]["assembly"].asString() == + BOOST_CHECK(contract["evm"]["assembly"].asString().find( " /* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x60)\n jumpi(tag_1, iszero(callvalue))\n" " invalid\ntag_1:\ntag_2:\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x0\n codecopy\n 0x0\n" " return\nstop\n\nsub_0: assembly {\n /* \"fileA\":0:14 contract A { } */\n" - " mstore(0x40, 0x60)\n tag_1:\n invalid\n}\n"); + " mstore(0x40, 0x60)\n tag_1:\n invalid\n\n" + " auxdata: 0xa165627a7a72305820") != std::string::npos); BOOST_CHECK(contract["evm"]["gasEstimates"].isObject()); BOOST_CHECK(dev::jsonCompactPrint(contract["evm"]["gasEstimates"]) == "{\"creation\":{\"codeDepositCost\":\"10200\",\"executionCost\":\"62\",\"totalCost\":\"10262\"}}"); @@ -217,7 +218,7 @@ BOOST_AUTO_TEST_CASE(basic_compilation) BOOST_CHECK(dev::jsonCompactPrint(result["sources"]["fileA"]["legacyAST"]) == "{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}},\"children\":" "[{\"attributes\":{\"baseContracts\":[null],\"contractDependencies\":[null],\"contractKind\":\"contract\"," - "\"fullyImplemented\":true,\"linearizedBaseContracts\":[1],\"name\":\"A\",\"nodes\":[null],\"scope\":2}," + "\"documentation\":null,\"fullyImplemented\":true,\"linearizedBaseContracts\":[1],\"name\":\"A\",\"nodes\":[null],\"scope\":2}," "\"id\":1,\"name\":\"ContractDefinition\",\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}"); } |