diff options
Diffstat (limited to 'test')
115 files changed, 1625 insertions, 620 deletions
diff --git a/test/ExecutionFramework.h b/test/ExecutionFramework.h index ee8da322..4525cbf9 100644 --- a/test/ExecutionFramework.h +++ b/test/ExecutionFramework.h @@ -53,6 +53,7 @@ class ExecutionFramework public: ExecutionFramework(); + virtual ~ExecutionFramework() = default; virtual bytes const& compileAndRunWithoutCheck( std::string const& _sourceCode, diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index 089be45d..4b399a14 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -1072,6 +1072,75 @@ BOOST_AUTO_TEST_CASE(cse_sub_zero) }); } +BOOST_AUTO_TEST_CASE(cse_remove_unwanted_masking_of_address) +{ + vector<Instruction> ops{ + Instruction::ADDRESS, + Instruction::CALLER, + Instruction::ORIGIN, + Instruction::COINBASE + }; + for (auto const& op: ops) + { + checkCSE({ + u256("0xffffffffffffffffffffffffffffffffffffffff"), + op, + Instruction::AND + }, { + op + }); + + checkCSE({ + op, + u256("0xffffffffffffffffffffffffffffffffffffffff"), + Instruction::AND + }, { + op + }); + + // do not remove mask for other masking + checkCSE({ + u256(1234), + op, + Instruction::AND + }, { + op, + u256(1234), + Instruction::AND + }); + + checkCSE({ + op, + u256(1234), + Instruction::AND + }, { + u256(1234), + op, + Instruction::AND + }); + } + + // leave other opcodes untouched + checkCSE({ + u256("0xffffffffffffffffffffffffffffffffffffffff"), + Instruction::CALLVALUE, + Instruction::AND + }, { + Instruction::CALLVALUE, + u256("0xffffffffffffffffffffffffffffffffffffffff"), + Instruction::AND + }); + + checkCSE({ + Instruction::CALLVALUE, + u256("0xffffffffffffffffffffffffffffffffffffffff"), + Instruction::AND + }, { + u256("0xffffffffffffffffffffffffffffffffffffffff"), + Instruction::CALLVALUE, + Instruction::AND + }); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libjulia/Inliner.cpp b/test/libjulia/Inliner.cpp index 88b51f28..464dcd93 100644 --- a/test/libjulia/Inliner.cpp +++ b/test/libjulia/Inliner.cpp @@ -1,18 +1,18 @@ /* - This file is part of solidity. + This file is part of solidity. - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with solidity. If not, see <http://www.gnu.org/licenses/>. + You should have received a copy of the GNU General Public License + along with solidity. If not, see <http://www.gnu.org/licenses/>. */ /** * @date 2017 @@ -23,6 +23,9 @@ #include <libjulia/optimiser/ExpressionInliner.h> #include <libjulia/optimiser/InlinableExpressionFunctionFinder.h> +#include <libjulia/optimiser/FullInliner.h> +#include <libjulia/optimiser/FunctionHoister.h> +#include <libjulia/optimiser/FunctionGrouper.h> #include <libsolidity/inlineasm/AsmPrinter.h> @@ -58,8 +61,17 @@ string inlineFunctions(string const& _source, bool _julia = true) ExpressionInliner(ast).run(); return assembly::AsmPrinter(_julia)(ast); } +string fullInline(string const& _source, bool _julia = true) +{ + Block ast = disambiguate(_source, _julia); + (FunctionHoister{})(ast); + (FunctionGrouper{})(ast);\ + FullInliner(ast).run(); + return assembly::AsmPrinter(_julia)(ast); +} } + BOOST_AUTO_TEST_SUITE(IuliaInlinableFunctionFilter) BOOST_AUTO_TEST_CASE(smoke_test) @@ -197,3 +209,135 @@ BOOST_AUTO_TEST_CASE(double_recursive_calls) } BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(IuliaFullInliner) + +BOOST_AUTO_TEST_CASE(simple) +{ + BOOST_CHECK_EQUAL( + fullInline("{" + "function f(a) -> x { let r := mul(a, a) x := add(r, r) }" + "let y := add(f(sload(mload(2))), mload(7))" + "}", false), + format("{" + "{" + "let _1 := mload(7)" + "let f_a := sload(mload(2))" + "let f_x" + "{" + "let f_r := mul(f_a, f_a)" + "f_x := add(f_r, f_r)" + "}" + "let y := add(f_x, _1)" + "}" + "function f(a) -> x" + "{" + "let r := mul(a, a)" + "x := add(r, r)" + "}" + "}", false) + ); +} + +BOOST_AUTO_TEST_CASE(multi_fun) +{ + BOOST_CHECK_EQUAL( + fullInline("{" + "function f(a) -> x { x := add(a, a) }" + "function g(b, c) -> y { y := mul(mload(c), f(b)) }" + "let y := g(f(3), 7)" + "}", false), + format("{" + "{" + "let g_c := 7 " + "let f_a_1 := 3 " + "let f_x_1 " + "{ f_x_1 := add(f_a_1, f_a_1) } " + "let g_y " + "{" + "let g_f_a := f_x_1 " + "let g_f_x " + "{" + "g_f_x := add(g_f_a, g_f_a)" + "}" + "g_y := mul(mload(g_c), g_f_x)" + "}" + "let y_1 := g_y" + "}" + "function f(a) -> x" + "{" + "x := add(a, a)" + "}" + "function g(b, c) -> y" + "{" + "let f_a := b " + "let f_x " + "{" + "f_x := add(f_a, f_a)" + "}" + "y := mul(mload(c), f_x)" + "}" + "}", false) + ); +} + +BOOST_AUTO_TEST_CASE(move_up_rightwards_arguments) +{ + BOOST_CHECK_EQUAL( + fullInline("{" + "function f(a, b, c) -> x { x := add(a, b) x := mul(x, c) }" + "let y := add(mload(1), add(f(mload(2), mload(3), mload(4)), mload(5)))" + "}", false), + format("{" + "{" + "let _1 := mload(5)" + "let f_c := mload(4)" + "let f_b := mload(3)" + "let f_a := mload(2)" + "let f_x" + "{" + "f_x := add(f_a, f_b)" + "f_x := mul(f_x, f_c)" + "}" + "let y := add(mload(1), add(f_x, _1))" + "}" + "function f(a, b, c) -> x" + "{" + "x := add(a, b)" + "x := mul(x, c)" + "}" + "}", false) + ); +} + +BOOST_AUTO_TEST_CASE(pop_result) +{ + // This tests that `pop(r)` is removed. + BOOST_CHECK_EQUAL( + fullInline("{" + "function f(a) -> x { let r := mul(a, a) x := add(r, r) }" + "pop(add(f(7), 2))" + "}", false), + format("{" + "{" + "let _1 := 2 " + "let f_a := 7 " + "let f_x " + "{" + "let f_r := mul(f_a, f_a) " + "f_x := add(f_r, f_r)" + "}" + "{" + "}" + "}" + "function f(a) -> x" + "{" + "let r := mul(a, a) " + "x := add(r, r)" + "}" + "}", false) + ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libjulia/MainFunction.cpp b/test/libjulia/MainFunction.cpp new file mode 100644 index 00000000..c26b002d --- /dev/null +++ b/test/libjulia/MainFunction.cpp @@ -0,0 +1,87 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * @date 2018 + * Unit tests for the Julia MainFunction transformation. + */ + +#include <test/libjulia/Common.h> + +#include <libjulia/optimiser/FunctionGrouper.h> +#include <libjulia/optimiser/MainFunction.h> + +#include <libsolidity/inlineasm/AsmPrinter.h> + +#include <boost/test/unit_test.hpp> + +using namespace std; +using namespace dev::julia; +using namespace dev::julia::test; +using namespace dev::solidity; + +#define CHECK(_original, _expectation)\ +do\ +{\ + assembly::AsmPrinter p(true);\ + Block b = disambiguate(_original);\ + (FunctionGrouper{})(b);\ + (MainFunction{})(b);\ + string result = p(b);\ + BOOST_CHECK_EQUAL(result, format(_expectation));\ +}\ +while(false) + +BOOST_AUTO_TEST_SUITE(JuliaMainFunction) + +BOOST_AUTO_TEST_CASE(smoke_test) +{ + CHECK("{ }", "{ function main() { } }"); +} + +BOOST_AUTO_TEST_CASE(single_fun) +{ + CHECK( + "{ let a:u256 function f() {} }", + "{ function main() { let a:u256 } function f() {} }" + ); +} + +BOOST_AUTO_TEST_CASE(multi_fun_mixed) +{ + CHECK( + "{ let a:u256 function f() { let b:u256 } let c:u256 function g() { let d:u256 } let e:u256 }", + "{ function main() { let a:u256 let c:u256 let e:u256 } function f() { let b:u256 } function g() { let d:u256 } }" + ); +} + +BOOST_AUTO_TEST_CASE(nested_fun) +{ + CHECK( + "{ let a:u256 function f() { let b:u256 function g() { let c:u256} let d:u256 } }", + "{ function main() { let a:u256 } function f() { let b:u256 function g() { let c:u256} let d:u256 } }" + ); +} + +BOOST_AUTO_TEST_CASE(empty_block) +{ + CHECK( + "{ let a:u256 { } function f() -> x:bool { let b:u256 := 4:u256 {} for {} f() {} {} } }", + "{ function main() { let a:u256 { } } function f() -> x:bool { let b:u256 := 4:u256 {} for {} f() {} {} } }" + ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libjulia/Parser.cpp b/test/libjulia/Parser.cpp index 9d66658e..96261dec 100644 --- a/test/libjulia/Parser.cpp +++ b/test/libjulia/Parser.cpp @@ -212,10 +212,10 @@ BOOST_AUTO_TEST_CASE(tokens_as_identifers) BOOST_AUTO_TEST_CASE(lacking_types) { - CHECK_ERROR("{ let x := 1:u256 }", ParserError, "Expected token Identifier got 'Assign'"); - CHECK_ERROR("{ let x:u256 := 1 }", ParserError, "Expected token Colon got 'RBrace'"); - CHECK_ERROR("{ function f(a) {} }", ParserError, "Expected token Colon got 'RParen'"); - CHECK_ERROR("{ function f(a:u256) -> b {} }", ParserError, "Expected token Colon got 'LBrace'"); + CHECK_ERROR("{ let x := 1:u256 }", ParserError, "Expected identifier but got '='"); + CHECK_ERROR("{ let x:u256 := 1 }", ParserError, "Expected ':' but got '}'"); + CHECK_ERROR("{ function f(a) {} }", ParserError, "Expected ':' but got ')'"); + CHECK_ERROR("{ function f(a:u256) -> b {} }", ParserError, "Expected ':' but got '{'"); } BOOST_AUTO_TEST_CASE(invalid_types) @@ -294,7 +294,7 @@ BOOST_AUTO_TEST_CASE(if_statement) BOOST_AUTO_TEST_CASE(if_statement_invalid) { CHECK_ERROR("{ if let x:u256 {} }", ParserError, "Literal or identifier expected."); - CHECK_ERROR("{ if true:bool let x:u256 := 3:u256 }", ParserError, "Expected token LBrace"); + CHECK_ERROR("{ if true:bool let x:u256 := 3:u256 }", ParserError, "Expected '{' but got reserved keyword 'let'"); // TODO change this to an error once we check types. BOOST_CHECK(successParse("{ if 42:u256 { } }")); } diff --git a/test/libsolidity/AnalysisFramework.h b/test/libsolidity/AnalysisFramework.h index 05490a42..a904617d 100644 --- a/test/libsolidity/AnalysisFramework.h +++ b/test/libsolidity/AnalysisFramework.h @@ -52,6 +52,7 @@ protected: bool _insertVersionPragma = true, bool _allowMultipleErrors = false ); + virtual ~AnalysisFramework() = default; SourceUnit const* parseAndAnalyse(std::string const& _source); bool success(std::string const& _source); diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index 77ca363a..7b3df043 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -158,8 +158,9 @@ BOOST_AUTO_TEST_CASE(location_test) } )"; AssemblyItems items = compileContract(sourceCode); + bool hasShifts = dev::test::Options::get().evmVersion().hasBitwiseShifting(); vector<SourceLocation> locations = - vector<SourceLocation>(24, SourceLocation(2, 75, make_shared<string>(""))) + + vector<SourceLocation>(hasShifts ? 23 : 24, SourceLocation(2, 75, make_shared<string>(""))) + vector<SourceLocation>(2, SourceLocation(20, 72, make_shared<string>(""))) + vector<SourceLocation>(1, SourceLocation(8, 17, make_shared<string>("--CODEGEN--"))) + vector<SourceLocation>(3, SourceLocation(5, 7, make_shared<string>("--CODEGEN--"))) + @@ -172,8 +173,6 @@ BOOST_AUTO_TEST_CASE(location_test) vector<SourceLocation>(1, SourceLocation(65, 67, make_shared<string>(""))) + vector<SourceLocation>(2, SourceLocation(58, 67, make_shared<string>(""))) + vector<SourceLocation>(2, SourceLocation(20, 72, make_shared<string>(""))); - - checkAssemblyLocations(items, locations); } diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp index 0d66456c..f16d9abe 100644 --- a/test/libsolidity/GasMeter.cpp +++ b/test/libsolidity/GasMeter.cpp @@ -307,6 +307,46 @@ BOOST_AUTO_TEST_CASE(regular_functions_exclude_fallback) testCreationTimeGas(sourceCode); testRunTimeGas("x()", vector<bytes>{encodeArgs()}); } + +BOOST_AUTO_TEST_CASE(complex_control_flow) +{ + // This crashed the gas estimator previously (or took a very long time). + // Now we do not follow branches if they start out with lower gas costs than the ones + // we previously considered. This of course reduces accuracy. + char const* sourceCode = R"( + contract log { + function ln(int128 x) constant returns (int128 result) { + int128 t = x / 256; + int128 y = 5545177; + x = t; + t = x * 16; if (t <= 1000000) { x = t; y = y - 2772588; } + t = x * 4; if (t <= 1000000) { x = t; y = y - 1386294; } + t = x * 2; if (t <= 1000000) { x = t; y = y - 693147; } + t = x + x / 2; if (t <= 1000000) { x = t; y = y - 405465; } + t = x + x / 4; if (t <= 1000000) { x = t; y = y - 223144; } + t = x + x / 8; if (t <= 1000000) { x = t; y = y - 117783; } + t = x + x / 16; if (t <= 1000000) { x = t; y = y - 60624; } + t = x + x / 32; if (t <= 1000000) { x = t; y = y - 30771; } + t = x + x / 64; if (t <= 1000000) { x = t; y = y - 15504; } + t = x + x / 128; if (t <= 1000000) { x = t; y = y - 7782; } + t = x + x / 256; if (t <= 1000000) { x = t; y = y - 3898; } + t = x + x / 512; if (t <= 1000000) { x = t; y = y - 1951; } + t = x + x / 1024; if (t <= 1000000) { x = t; y = y - 976; } + t = x + x / 2048; if (t <= 1000000) { x = t; y = y - 488; } + t = x + x / 4096; if (t <= 1000000) { x = t; y = y - 244; } + t = x + x / 8192; if (t <= 1000000) { x = t; y = y - 122; } + t = x + x / 16384; if (t <= 1000000) { x = t; y = y - 61; } + t = x + x / 32768; if (t <= 1000000) { x = t; y = y - 31; } + t = x + x / 65536; if (t <= 1000000) { y = y - 15; } + return y; + } + } + )"; + testCreationTimeGas(sourceCode); + // max gas is used for small x + testRunTimeGas("ln(int128)", vector<bytes>{encodeArgs(0), encodeArgs(10), encodeArgs(105), encodeArgs(30000)}); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 0ced1792..181ca959 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -170,7 +170,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) BOOST_AUTO_TEST_CASE(surplus_input) { - CHECK_PARSE_ERROR("{ } { }", ParserError, "Expected token EOS"); + CHECK_PARSE_ERROR("{ } { }", ParserError, "Expected end of source but got '{'"); } BOOST_AUTO_TEST_CASE(simple_instructions) @@ -246,7 +246,7 @@ BOOST_AUTO_TEST_CASE(functional) BOOST_AUTO_TEST_CASE(functional_partial) { - CHECK_PARSE_ERROR("{ let x := byte }", ParserError, "Expected token \"(\""); + CHECK_PARSE_ERROR("{ let x := byte }", ParserError, "Expected '(' (instruction \"byte\" expects 2 arguments)"); } BOOST_AUTO_TEST_CASE(functional_partial_success) @@ -290,10 +290,10 @@ BOOST_AUTO_TEST_CASE(if_statement_scope) BOOST_AUTO_TEST_CASE(if_statement_invalid) { - CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected token \"(\""); + CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected '(' (instruction \"mload\" expects 1 arguments)"); BOOST_CHECK("{ if calldatasize() {}"); CHECK_PARSE_ERROR("{ if mstore(1, 1) {} }", ParserError, "Instruction \"mstore\" not allowed in this context"); - CHECK_PARSE_ERROR("{ if 32 let x := 3 }", ParserError, "Expected token LBrace"); + CHECK_PARSE_ERROR("{ if 32 let x := 3 }", ParserError, "Expected '{' but got reserved keyword 'let'"); } BOOST_AUTO_TEST_CASE(switch_statement) @@ -320,7 +320,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("{ switch mload default {} }", ParserError, "Expected token \"(\""); + CHECK_PARSE_ERROR("{ switch mload default {} }", ParserError, "Expected '(' (instruction \"mload\" expects 1 arguments)"); CHECK_PARSE_ERROR("{ switch mstore(1, 1) default {} }", ParserError, "Instruction \"mstore\" not allowed in this context"); } @@ -341,7 +341,7 @@ BOOST_AUTO_TEST_CASE(switch_invalid_case) BOOST_AUTO_TEST_CASE(switch_invalid_body) { - CHECK_PARSE_ERROR("{ switch 42 case 1 mul case 2 {} default {} }", ParserError, "Expected token LBrace got 'Identifier'"); + CHECK_PARSE_ERROR("{ switch 42 case 1 mul case 2 {} default {} }", ParserError, "Expected '{' but got identifier"); } BOOST_AUTO_TEST_CASE(for_statement) @@ -353,10 +353,10 @@ BOOST_AUTO_TEST_CASE(for_statement) BOOST_AUTO_TEST_CASE(for_invalid_expression) { CHECK_PARSE_ERROR("{ for {} {} {} {} }", ParserError, "Literal, identifier or instruction expected."); - CHECK_PARSE_ERROR("{ for 1 1 {} {} }", ParserError, "Expected token LBrace got 'Number'"); - CHECK_PARSE_ERROR("{ for {} 1 1 {} }", ParserError, "Expected token LBrace got 'Number'"); - CHECK_PARSE_ERROR("{ for {} 1 {} 1 }", ParserError, "Expected token LBrace got 'Number'"); - CHECK_PARSE_ERROR("{ for {} mload {} {} }", ParserError, "Expected token \"(\""); + CHECK_PARSE_ERROR("{ for 1 1 {} {} }", ParserError, "Expected '{' but got 'Number'"); + CHECK_PARSE_ERROR("{ for {} 1 1 {} }", ParserError, "Expected '{' but got 'Number'"); + CHECK_PARSE_ERROR("{ for {} 1 {} 1 }", ParserError, "Expected '{' but got 'Number'"); + CHECK_PARSE_ERROR("{ for {} mload {} {} }", ParserError, "Expected '(' (instruction \"mload\" expects 1 arguments)"); CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", ParserError, "Instruction \"mstore\" not allowed in this context"); } @@ -437,13 +437,13 @@ BOOST_AUTO_TEST_CASE(invalid_tuple_assignment) BOOST_AUTO_TEST_CASE(instruction_too_few_arguments) { - CHECK_PARSE_ERROR("{ mul() }", ParserError, "Expected expression (\"mul\" expects 2 arguments)"); - CHECK_PARSE_ERROR("{ mul(1) }", ParserError, "Expected comma (\"mul\" expects 2 arguments)"); + CHECK_PARSE_ERROR("{ mul() }", ParserError, "Expected expression (instruction \"mul\" expects 2 arguments)"); + CHECK_PARSE_ERROR("{ mul(1) }", ParserError, "Expected ',' (instruction \"mul\" expects 2 arguments)"); } BOOST_AUTO_TEST_CASE(instruction_too_many_arguments) { - CHECK_PARSE_ERROR("{ mul(1, 2, 3) }", ParserError, "Expected ')' (\"mul\" expects 2 arguments)"); + CHECK_PARSE_ERROR("{ mul(1, 2, 3) }", ParserError, "Expected ')' (instruction \"mul\" expects 2 arguments)"); } BOOST_AUTO_TEST_CASE(recursion_depth) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 789b89d1..4b09d253 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -2105,7 +2105,7 @@ BOOST_AUTO_TEST_CASE(packed_keccak256_complex_types) char const* sourceCode = R"( contract test { uint120[3] x; - function f() view returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) { + function f() returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) { uint120[] memory y = new uint120[](3); x[0] = y[0] = uint120(-2); x[1] = y[1] = uint120(-3); @@ -10122,6 +10122,23 @@ BOOST_AUTO_TEST_CASE(shift_right_assignment) ABI_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(17)), encodeArgs(u256(0))); } +BOOST_AUTO_TEST_CASE(shift_right_assignment_signed) +{ + char const* sourceCode = R"( + contract C { + function f(int a, int b) returns (int) { + a >>= b; + return a; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(0x4266), u256(0)), encodeArgs(u256(0x4266))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(0x4266), u256(8)), encodeArgs(u256(0x42))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(0x4266), u256(16)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(0x4266), u256(17)), encodeArgs(u256(0))); +} + BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue) { char const* sourceCode = R"( @@ -10133,9 +10150,141 @@ BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue) )"; compileAndRun(sourceCode, 0, "C"); ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(0)), encodeArgs(u256(-4266))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(1)), encodeArgs(u256(-2133))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(4)), encodeArgs(u256(-266))); ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(8)), encodeArgs(u256(-16))); ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(16)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(17)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(0)), encodeArgs(u256(-4267))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(1)), encodeArgs(u256(-2133))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(4)), encodeArgs(u256(-266))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(8)), encodeArgs(u256(-16))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(16)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(17)), encodeArgs(u256(0))); +} + +BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_int8) +{ + char const* sourceCode = R"( + contract C { + function f(int8 a, int8 b) returns (int) { + return a >> b; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(0)), encodeArgs(u256(-66))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(1)), encodeArgs(u256(-33))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(4)), encodeArgs(u256(-4))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(8)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(16)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(17)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(0)), encodeArgs(u256(-67))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(1)), encodeArgs(u256(-33))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(4)), encodeArgs(u256(-4))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(8)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(16)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(17)), encodeArgs(u256(0))); +} + +BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_signextend_int8) +{ + char const* sourceCode = R"( + contract C { + function f(int8 a, int8 b) returns (int8) { + return a >> b; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(0)), encodeArgs(u256(-103))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(1)), encodeArgs(u256(-51))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(2)), encodeArgs(u256(-25))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(4)), encodeArgs(u256(-6))); + ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(8)), encodeArgs(u256(0))); +} + +BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_signextend_int16) +{ + char const* sourceCode = R"( + contract C { + function f(int16 a, int16 b) returns (int16) { + return a >> b; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(0)), encodeArgs(u256(-103))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(1)), encodeArgs(u256(-51))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(2)), encodeArgs(u256(-25))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(4)), encodeArgs(u256(-6))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(8)), encodeArgs(u256(0))); +} + +BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_signextend_int32) +{ + char const* sourceCode = R"( + contract C { + function f(int32 a, int32 b) returns (int32) { + return a >> b; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(0)), encodeArgs(u256(-103))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(1)), encodeArgs(u256(-51))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(2)), encodeArgs(u256(-25))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(4)), encodeArgs(u256(-6))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(8)), encodeArgs(u256(0))); +} + + +BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_int16) +{ + char const* sourceCode = R"( + contract C { + function f(int16 a, int16 b) returns (int) { + return a >> b; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(0)), encodeArgs(u256(-4266))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(1)), encodeArgs(u256(-2133))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(4)), encodeArgs(u256(-266))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(8)), encodeArgs(u256(-16))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(16)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(17)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(0)), encodeArgs(u256(-4267))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(1)), encodeArgs(u256(-2133))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(4)), encodeArgs(u256(-266))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(8)), encodeArgs(u256(-16))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(16)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(17)), encodeArgs(u256(0))); +} + +BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_int32) +{ + char const* sourceCode = R"( + contract C { + function f(int32 a, int32 b) returns (int) { + return a >> b; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(0)), encodeArgs(u256(-4266))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(1)), encodeArgs(u256(-2133))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(4)), encodeArgs(u256(-266))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(8)), encodeArgs(u256(-16))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(16)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(17)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(0)), encodeArgs(u256(-4267))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(1)), encodeArgs(u256(-2133))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(4)), encodeArgs(u256(-266))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(8)), encodeArgs(u256(-16))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(16)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(17)), encodeArgs(u256(0))); } BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_assignment) @@ -10150,9 +10299,17 @@ BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_assignment) )"; compileAndRun(sourceCode, 0, "C"); ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(0)), encodeArgs(u256(-4266))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(1)), encodeArgs(u256(-2133))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(4)), encodeArgs(u256(-266))); ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(8)), encodeArgs(u256(-16))); ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(16)), encodeArgs(u256(0))); ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(17)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(0)), encodeArgs(u256(-4267))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(1)), encodeArgs(u256(-2133))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(4)), encodeArgs(u256(-266))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(8)), encodeArgs(u256(-16))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(16)), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(17)), encodeArgs(u256(0))); } BOOST_AUTO_TEST_CASE(shift_negative_rvalue) @@ -10720,9 +10877,9 @@ BOOST_AUTO_TEST_CASE(negative_stack_height) bool Aboolc; bool exists; } - function nredit(uint startindex) public constant returns(uint[500] CIDs, uint[500] dates, uint[500] RIDs, bool[500] Cboolas, uint[500] amounts){} - function return500InvoicesByDates(uint begindate, uint enddate, uint startindex) public constant returns(uint[500] AIDs, bool[500] Aboolas, uint[500] dates, bytes32[3][500] Abytesas, bytes32[3][500] bytesbs, bytes32[2][500] bytescs, uint[500] amounts, bool[500] Aboolbs, bool[500] Aboolcs){} - function return500PaymentsByDates(uint begindate, uint enddate, uint startindex) public constant returns(uint[500] BIDs, uint[500] dates, uint[500] RIDs, bool[500] Bboolas, bytes32[3][500] bytesbs,bytes32[2][500] bytescs, uint[500] amounts, bool[500] Bboolbs){} + function nredit(uint startindex) public pure returns(uint[500] CIDs, uint[500] dates, uint[500] RIDs, bool[500] Cboolas, uint[500] amounts){} + function return500InvoicesByDates(uint begindate, uint enddate, uint startindex) public view returns(uint[500] AIDs, bool[500] Aboolas, uint[500] dates, bytes32[3][500] Abytesas, bytes32[3][500] bytesbs, bytes32[2][500] bytescs, uint[500] amounts, bool[500] Aboolbs, bool[500] Aboolcs){} + function return500PaymentsByDates(uint begindate, uint enddate, uint startindex) public view returns(uint[500] BIDs, uint[500] dates, uint[500] RIDs, bool[500] Bboolas, bytes32[3][500] bytesbs,bytes32[2][500] bytescs, uint[500] amounts, bool[500] Bboolbs){} } )"; compileAndRun(sourceCode, 0, "C"); @@ -10908,13 +11065,13 @@ BOOST_AUTO_TEST_CASE(bare_call_invalid_address) char const* sourceCode = R"( contract C { /// Calling into non-existant account is successful (creates the account) - function f() external view returns (bool) { + function f() external returns (bool) { return address(0x4242).call(); } - function g() external view returns (bool) { + function g() external returns (bool) { return address(0x4242).callcode(); } - function h() external view returns (bool) { + function h() external returns (bool) { return address(0x4242).delegatecall(); } } @@ -10936,13 +11093,13 @@ BOOST_AUTO_TEST_CASE(delegatecall_return_value) function get() external view returns (uint) { return value; } - function get_delegated() external view returns (bool) { + function get_delegated() external returns (bool) { return this.delegatecall(bytes4(sha3("get()"))); } function assert0() external view { assert(value == 0); } - function assert0_delegated() external view returns (bool) { + function assert0_delegated() external returns (bool) { return this.delegatecall(bytes4(sha3("assert0()"))); } } @@ -11403,7 +11560,7 @@ BOOST_AUTO_TEST_CASE(abi_encode_v2) require(y[0] == "e"); } S s; - function f4() public view returns (bytes r) { + function f4() public returns (bytes r) { string memory x = "abc"; s.a = 7; s.b.push(2); @@ -11881,6 +12038,26 @@ BOOST_AUTO_TEST_CASE(bitwise_shifting_constants_constantinople) BOOST_CHECK(callContractFunction("shr_3()") == encodeArgs(u256(1))); } +BOOST_AUTO_TEST_CASE(senders_balance) +{ + char const* sourceCode = R"( + contract C { + function f() public view returns (uint) { + return msg.sender.balance; + } + } + contract D { + C c = new C(); + constructor() payable { } + function f() public view returns (uint) { + return c.f(); + } + } + )"; + compileAndRun(sourceCode, 27, "D"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(27))); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 97cf0410..5af67659 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -831,24 +831,6 @@ BOOST_AUTO_TEST_CASE(illegal_override_visibility) CHECK_ERROR(text, TypeError, "Overriding function visibility differs"); } -BOOST_AUTO_TEST_CASE(illegal_override_remove_constness) -{ - char const* text = R"( - contract B { function f() constant {} } - contract C is B { function f() public {} } - )"; - CHECK_ERROR(text, TypeError, "Overriding function changes state mutability from \"view\" to \"nonpayable\"."); -} - -BOOST_AUTO_TEST_CASE(illegal_override_add_constness) -{ - char const* text = R"( - contract B { function f() public {} } - contract C is B { function f() constant {} } - )"; - CHECK_ERROR(text, TypeError, "Overriding function changes state mutability from \"nonpayable\" to \"view\"."); -} - BOOST_AUTO_TEST_CASE(complex_inheritance) { char const* text = R"( @@ -993,19 +975,6 @@ BOOST_AUTO_TEST_CASE(private_state_variable) BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of an internal variable should not exist"); } -BOOST_AUTO_TEST_CASE(missing_state_variable) -{ - char const* text = R"( - contract Scope { - function getStateVar() constant public returns (uint stateVar) { - stateVar = Scope.stateVar; // should fail. - } - } - )"; - CHECK_ERROR(text, TypeError, "Member \"stateVar\" not found or not visible after argument-dependent lookup in type(contract Scope)"); -} - - BOOST_AUTO_TEST_CASE(base_class_state_variable_accessor) { // test for issue #1126 https://github.com/ethereum/cpp-ethereum/issues/1126 @@ -1119,17 +1088,6 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_return_parameters) CHECK_ERROR(text, TypeError, "Fallback function cannot return values."); } -BOOST_AUTO_TEST_CASE(fallback_function_with_constant_modifier) -{ - char const* text = R"( - contract C { - uint x; - function() constant { x = 2; } - } - )"; - CHECK_ERROR(text, TypeError, "Fallback function must be payable or non-payable"); -} - BOOST_AUTO_TEST_CASE(fallback_function_twice) { char const* text = R"( @@ -2278,25 +2236,6 @@ BOOST_AUTO_TEST_CASE(explicit_conversion_from_decimal_to_bytesxx) CHECK_SUCCESS_NO_WARNINGS(text); } -BOOST_AUTO_TEST_CASE(combining_hex_and_denomination) -{ - char const* text = R"( - contract Foo { - uint constant x = 0x01 wei; - } - )"; - CHECK_WARNING(text, "Hexadecimal numbers with unit denominations are deprecated."); - - char const* textV050 = R"( - pragma experimental "v0.5.0"; - - contract Foo { - uint constant x = 0x01 wei; - } - )"; - CHECK_ERROR(textV050, TypeError, "Hexadecimal numbers cannot be used with unit denominations."); -} - BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable) { char const* text = R"( @@ -2346,30 +2285,6 @@ BOOST_AUTO_TEST_CASE(constant_string_literal_disallows_assignment) CHECK_ERROR(text, TypeError, "Index access for string is not possible."); } -BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant_0_4_x) -{ - char const* text = R"( - contract C { - function () constant returns (uint) x; - uint constant y = x(); - } - )"; - CHECK_WARNING(text, "Initial value for constant variable has to be compile-time constant."); -} - -BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant) -{ - char const* text = R"( - pragma experimental "v0.5.0"; - - contract C { - function () constant returns (uint) x; - uint constant y = x(); - } - )"; - CHECK_ERROR(text, TypeError, "Initial value for constant variable has to be compile-time constant."); -} - BOOST_AUTO_TEST_CASE(assignment_to_const_var_involving_conversion) { char const* text = R"( @@ -2913,7 +2828,7 @@ BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible) contract C { function f(uint) public returns (string); function g() public { - var (x,) = this.f(2); + var x = this.f(2); // we can assign to x but it is not usable. bytes(x).length; } @@ -5823,7 +5738,7 @@ BOOST_AUTO_TEST_CASE(bare_others) CHECK_WARNING("contract C { function f() pure public { assert; } }", "Statement has no effect."); // This is different because it does have overloads. CHECK_ERROR("contract C { function f() pure public { require; } }", TypeError, "No matching declaration found after variable lookup."); - CHECK_WARNING("contract C { function f() pure public { suicide; } }", "Statement has no effect."); + CHECK_WARNING("contract C { function f() pure public { selfdestruct; } }", "Statement has no effect."); } BOOST_AUTO_TEST_CASE(pure_statement_in_for_loop) @@ -5852,80 +5767,6 @@ BOOST_AUTO_TEST_CASE(pure_statement_check_for_regular_for_loop) CHECK_SUCCESS(text); } -BOOST_AUTO_TEST_CASE(warn_multiple_storage_storage_copies) -{ - char const* text = R"( - contract C { - struct S { uint a; uint b; } - S x; S y; - function f() public { - (x, y) = (y, x); - } - } - )"; - CHECK_WARNING(text, "This assignment performs two copies to storage."); -} - -BOOST_AUTO_TEST_CASE(warn_multiple_storage_storage_copies_fill_right) -{ - char const* text = R"( - contract C { - struct S { uint a; uint b; } - S x; S y; - function f() public { - (x, y, ) = (y, x, 1, 2); - } - } - )"; - CHECK_WARNING(text, "This assignment performs two copies to storage."); -} - -BOOST_AUTO_TEST_CASE(warn_multiple_storage_storage_copies_fill_left) -{ - char const* text = R"( - contract C { - struct S { uint a; uint b; } - S x; S y; - function f() public { - (,x, y) = (1, 2, y, x); - } - } - )"; - CHECK_WARNING(text, "This assignment performs two copies to storage."); -} - -BOOST_AUTO_TEST_CASE(nowarn_swap_memory) -{ - char const* text = R"( - contract C { - struct S { uint a; uint b; } - function f() pure public { - S memory x; - S memory y; - (x, y) = (y, x); - } - } - )"; - CHECK_SUCCESS_NO_WARNINGS(text); -} - -BOOST_AUTO_TEST_CASE(nowarn_swap_storage_pointers) -{ - char const* text = R"( - contract C { - struct S { uint a; uint b; } - S x; S y; - function f() public { - S storage x_local = x; - S storage y_local = y; - S storage z_local = x; - (x, y_local, x_local, z_local) = (y, x_local, y_local, y); - } - } - )"; - CHECK_SUCCESS_NO_WARNINGS(text); -} - BOOST_AUTO_TEST_CASE(warn_unused_local) { char const* text = R"( @@ -6958,31 +6799,6 @@ BOOST_AUTO_TEST_CASE(invalid_literal_in_tuple) CHECK_SUCCESS(text); } -BOOST_AUTO_TEST_CASE(warn_about_sha3) -{ - char const* text = R"( - contract test { - function f() pure public { - bytes32 x = sha3(uint8(1)); - x; - } - } - )"; - CHECK_WARNING(text, "\"sha3\" has been deprecated in favour of \"keccak256\""); -} - -BOOST_AUTO_TEST_CASE(warn_about_suicide) -{ - char const* text = R"( - contract test { - function f() public { - suicide(1); - } - } - )"; - CHECK_WARNING(text, "\"suicide\" has been deprecated in favour of \"selfdestruct\""); -} - BOOST_AUTO_TEST_CASE(address_overload_resolution) { char const* text = R"( diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index 100b3662..cbea8694 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -112,61 +112,6 @@ while(0) BOOST_AUTO_TEST_SUITE(SolidityParser) -BOOST_AUTO_TEST_CASE(empty_function) -{ - 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 = R"( - contract test { - uint256 stateVar; - function functionName() {} - } - )"; - BOOST_CHECK(successParse(text)); -} - -BOOST_AUTO_TEST_CASE(single_function_param) -{ - char const* text = R"( - contract test { - uint256 stateVar; - function functionName(bytes32 input) returns (bytes32 out) {} - } - )"; - BOOST_CHECK(successParse(text)); -} - -BOOST_AUTO_TEST_CASE(single_function_param_trailing_comma) -{ - char const* text = R"( - contract test { - function(uint a,) {} - } - )"; - CHECK_PARSE_ERROR(text, "Unexpected trailing comma in parameter list."); -} - -BOOST_AUTO_TEST_CASE(single_return_param_trailing_comma) -{ - char const* text = R"( - contract test { - function() returns (uint a,) {} - } - )"; - CHECK_PARSE_ERROR(text, "Unexpected trailing comma in parameter list."); -} - BOOST_AUTO_TEST_CASE(single_modifier_arg_trailing_comma) { char const* text = R"( @@ -241,39 +186,6 @@ BOOST_AUTO_TEST_CASE(function_no_body) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(missing_parameter_name_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({: 1, : 2, : 3}); } - } - )"; - CHECK_PARSE_ERROR(text, "Expected identifier"); -} - -BOOST_AUTO_TEST_CASE(missing_argument_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: , b: , c: }); } - } - )"; - 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"( @@ -557,18 +469,6 @@ BOOST_AUTO_TEST_CASE(variable_definition_with_initialization) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(variable_definition_in_mapping) -{ - char const* text = R"( - contract test { - function fun() { - mapping(var=>bytes32) d; - } - } - )"; - CHECK_PARSE_ERROR(text, "Expected elementary type name for mapping key type"); -} - BOOST_AUTO_TEST_CASE(operator_expression) { char const* text = R"( @@ -849,16 +749,6 @@ BOOST_AUTO_TEST_CASE(modifier) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(modifier_without_semicolon) -{ - 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 = R"( @@ -918,16 +808,6 @@ BOOST_AUTO_TEST_CASE(event_arguments_indexed) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(event_with_no_argument_list_fails) -{ - char const* text = R"( - contract c { - event e; - } - )"; - CHECK_PARSE_ERROR(text, "Expected token LParen got 'Semicolon'"); -} - BOOST_AUTO_TEST_CASE(visibility_specifiers) { char const* text = R"( @@ -958,40 +838,6 @@ BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers) CHECK_PARSE_ERROR(text, "Visibility already specified as \"private\"."); } -BOOST_AUTO_TEST_CASE(multiple_statemutability_specifiers) -{ - char const* text = R"( - contract c { - function f() payable payable {} - })"; - CHECK_PARSE_ERROR(text, "State mutability already specified as \"payable\"."); - text = R"( - contract c { - function f() constant constant {} - })"; - CHECK_PARSE_ERROR(text, "State mutability already specified as \"view\"."); - text = R"( - contract c { - function f() constant view {} - })"; - CHECK_PARSE_ERROR(text, "State mutability already specified as \"view\"."); - text = R"( - contract c { - function f() payable constant {} - })"; - CHECK_PARSE_ERROR(text, "State mutability already specified as \"payable\"."); - text = R"( - contract c { - function f() pure payable {} - })"; - CHECK_PARSE_ERROR(text, "State mutability already specified as \"pure\"."); - text = R"( - contract c { - function f() pure constant {} - })"; - CHECK_PARSE_ERROR(text, "State mutability already specified as \"pure\"."); -} - BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations) { char const* text = R"( @@ -1038,24 +884,6 @@ BOOST_AUTO_TEST_CASE(enum_valid_declaration) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(empty_enum_declaration) -{ - char const* text = R"( - contract c { - enum foo { } - })"; - CHECK_PARSE_ERROR(text, "enum with no members is not allowed"); -} - -BOOST_AUTO_TEST_CASE(malformed_enum_declaration) -{ - char const* text = R"( - contract c { - enum foo { WARNING,} - })"; - CHECK_PARSE_ERROR(text, "Expected Identifier after"); -} - BOOST_AUTO_TEST_CASE(external_function) { char const* text = R"( @@ -1065,15 +893,6 @@ BOOST_AUTO_TEST_CASE(external_function) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(external_variable) -{ - char const* text = R"( - contract c { - uint external x; - })"; - CHECK_PARSE_ERROR(text, "Expected identifier"); -} - BOOST_AUTO_TEST_CASE(arrays_in_storage) { char const* text = R"( @@ -1113,15 +932,6 @@ BOOST_AUTO_TEST_CASE(multi_arrays) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(constant_is_keyword) -{ - char const* text = R"( - contract Foo { - uint constant = 4; - })"; - CHECK_PARSE_ERROR(text, "Expected identifier"); -} - BOOST_AUTO_TEST_CASE(keyword_is_reserved) { auto keywords = { @@ -1148,19 +958,10 @@ BOOST_AUTO_TEST_CASE(keyword_is_reserved) for (const auto& keyword: keywords) { auto text = std::string("contract ") + keyword + " {}"; - CHECK_PARSE_ERROR(text.c_str(), "Expected identifier"); + CHECK_PARSE_ERROR(text.c_str(), "Expected identifier but got reserved keyword"); } } -BOOST_AUTO_TEST_CASE(var_array) -{ - char const* text = R"( - contract Foo { - function f() { var[] a; } - })"; - CHECK_PARSE_ERROR(text, "Expected identifier"); -} - BOOST_AUTO_TEST_CASE(location_specifiers_for_params) { char const* text = R"( @@ -1184,24 +985,6 @@ BOOST_AUTO_TEST_CASE(location_specifiers_for_locals) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(location_specifiers_for_state) -{ - char const* text = R"( - contract Foo { - uint[] memory x; - })"; - CHECK_PARSE_ERROR(text, "Expected identifier"); -} - -BOOST_AUTO_TEST_CASE(location_specifiers_with_var) -{ - char const* text = R"( - contract Foo { - function f() { var memory x; } - })"; - CHECK_PARSE_ERROR(text, "Location specifier needs explicit type name"); -} - BOOST_AUTO_TEST_CASE(empty_comment) { char const* text = R"( @@ -1224,7 +1007,6 @@ BOOST_AUTO_TEST_CASE(comment_end_with_double_star) BOOST_CHECK(successParse(text)); } - BOOST_AUTO_TEST_CASE(library_simple) { char const* text = R"( @@ -1235,20 +1017,6 @@ BOOST_AUTO_TEST_CASE(library_simple) BOOST_CHECK(successParse(text)); } - -BOOST_AUTO_TEST_CASE(local_const_variable) -{ - char const* text = R"( - contract Foo { - function localConst() returns (uint ret) - { - uint constant local = 4; - return local; - } - })"; - CHECK_PARSE_ERROR(text, "Expected token Semicolon"); -} - BOOST_AUTO_TEST_CASE(multi_variable_declaration) { char const* text = R"( @@ -1285,18 +1053,6 @@ BOOST_AUTO_TEST_CASE(tuples) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(tuples_without_commas) -{ - char const* text = R"( - contract C { - function f() { - var a = (2 2); - } - } - )"; - CHECK_PARSE_ERROR(text, "Expected token Comma"); -} - BOOST_AUTO_TEST_CASE(member_access_parser_ambiguity) { char const* text = R"( @@ -1365,34 +1121,6 @@ BOOST_AUTO_TEST_CASE(inline_array_declaration) BOOST_CHECK(successParse(text)); } - -BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_lvalue) -{ - char const* text = R"( - contract c { - uint[] a; - function f() returns (uint) { - a = [,2,3]; - return (a[0]); - } - } - )"; - CHECK_PARSE_ERROR(text, "Expected expression"); -} - -BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_without_lvalue) -{ - char const* text = R"( - contract c { - uint[] a; - function f() returns (uint, uint) { - return ([3, ,4][0]); - } - } - )"; - CHECK_PARSE_ERROR(text, "Expected expression"); -} - BOOST_AUTO_TEST_CASE(conditional_true_false_literal) { char const* text = R"( @@ -1520,38 +1248,6 @@ BOOST_AUTO_TEST_CASE(declaring_fixed_literal_variables) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(no_double_radix_in_fixed_literal) -{ - char const* text = R"( - contract A { - fixed40x40 pi = 3.14.15; - } - )"; - CHECK_PARSE_ERROR(text, "Expected token Semicolon"); -} - -BOOST_AUTO_TEST_CASE(invalid_fixed_conversion_leading_zeroes_check) -{ - char const* text = R"( - contract test { - function f() { - fixed a = 1.0x2; - } - } - )"; - CHECK_PARSE_ERROR(text, "Expected primary expression"); -} - -BOOST_AUTO_TEST_CASE(payable_accessor) -{ - char const* text = R"( - contract test { - uint payable x; - } - )"; - CHECK_PARSE_ERROR(text, "Expected identifier"); -} - BOOST_AUTO_TEST_CASE(function_type_in_expression) { char const* text = R"( @@ -1575,16 +1271,6 @@ BOOST_AUTO_TEST_CASE(function_type_as_storage_variable) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(function_type_as_storage_variable_with_modifiers) -{ - char const* text = R"( - contract test { - function (uint, uint) modifier1() returns (uint) f1; - } - )"; - CHECK_PARSE_ERROR(text, "Expected token LBrace"); -} - BOOST_AUTO_TEST_CASE(function_type_as_storage_variable_with_assignment) { char const* text = R"( @@ -1660,20 +1346,6 @@ BOOST_AUTO_TEST_CASE(function_type_state_variable) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(scientific_notation) -{ - char const* text = R"( - contract test { - uint256 a = 2e10; - uint256 b = 2E10; - uint256 c = 200e-2; - uint256 d = 2E10 wei; - uint256 e = 2.5e10; - } - )"; - BOOST_CHECK(successParse(text)); -} - BOOST_AUTO_TEST_CASE(interface) { char const* text = R"( @@ -1684,31 +1356,6 @@ BOOST_AUTO_TEST_CASE(interface) BOOST_CHECK(successParse(text)); } -BOOST_AUTO_TEST_CASE(newInvalidTypeName) -{ - char const* text = R"( - contract C { - function f() { - new var; - } - } - )"; - CHECK_PARSE_ERROR(text, "Expected explicit type name"); -} - -BOOST_AUTO_TEST_CASE(emitWithoutEvent) -{ - char const* text = R"( - contract C { - event A(); - function f() { - emit A; - } - } - )"; - CHECK_PARSE_ERROR(text, "Expected token LParen got 'Semicolon'"); -} - BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 74bf01b2..63c03881 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -326,9 +326,9 @@ BOOST_AUTO_TEST_CASE(compilation_error) { BOOST_CHECK_EQUAL( dev::jsonCompactPrint(error), - "{\"component\":\"general\",\"formattedMessage\":\"fileA:1:23: ParserError: Expected identifier, got 'RBrace'\\n" - "contract A { function }\\n ^\\n\",\"message\":\"Expected identifier, got 'RBrace'\"," - "\"severity\":\"error\",\"sourceLocation\":{\"end\":22,\"file\":\"fileA\",\"start\":22},\"type\":\"ParserError\"}" + "{\"component\":\"general\",\"formattedMessage\":\"fileA:1:23: ParserError: Expected identifier but got '}'\\n" + "contract A { function }\\n ^\\n\",\"message\":\"Expected identifier but got '}'\"," + "\"severity\":\"error\",\"sourceLocation\":{\"end\":23,\"file\":\"fileA\",\"start\":22},\"type\":\"ParserError\"}" ); } } diff --git a/test/libsolidity/syntaxTests/constants/assign_constant_function_value.sol b/test/libsolidity/syntaxTests/constants/assign_constant_function_value.sol new file mode 100644 index 00000000..88e94e29 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/assign_constant_function_value.sol @@ -0,0 +1,6 @@ +contract C { + function () pure returns (uint) x; + uint constant y = x(); +} +// ---- +// Warning: (74-77): Initial value for constant variable has to be compile-time constant. This will fail to compile with the next breaking version change. diff --git a/test/libsolidity/syntaxTests/constants/assign_constant_function_value_050.sol b/test/libsolidity/syntaxTests/constants/assign_constant_function_value_050.sol new file mode 100644 index 00000000..2c92899d --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/assign_constant_function_value_050.sol @@ -0,0 +1,8 @@ +pragma experimental "v0.5.0"; + +contract C { + function () pure returns (uint) x; + uint constant y = x(); +} +// ---- +// TypeError: (105-108): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly_fine.sol new file mode 100644 index 00000000..65902cc8 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly_fine.sol @@ -0,0 +1,26 @@ +contract C { + struct S { bool f; } + S s; + function f() internal returns (S storage c) { + assembly { + sstore(c_slot, sload(s_slot)) + } + } + function g(bool flag) internal returns (S storage c) { + // control flow in assembly will not be analyzed for now, + // so this will not issue a warning + assembly { + if flag { + sstore(c_slot, sload(s_slot)) + } + } + } + function h() internal returns (S storage c) { + // any reference from assembly will be sufficient for now, + // so this will not issue a warning + assembly { + sstore(s_slot, sload(c_slot)) + } + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly_warn.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly_warn.sol new file mode 100644 index 00000000..09c13847 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly_warn.sol @@ -0,0 +1,10 @@ +contract C { + struct S { bool f; } + S s; + function f() internal pure returns (S storage) { + assembly { + } + } +} +// ---- +// Warning: (87-88): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/default_location.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/default_location.sol new file mode 100644 index 00000000..9a42192d --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/default_location.sol @@ -0,0 +1,19 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S c) { + c = s; + } + function g() internal view returns (S) { + return s; + } + function h() internal pure returns (S) { + } + function i(bool flag) internal view returns (S c) { + if (flag) c = s; + } + function j(bool flag) internal view returns (S) { + if (flag) return s; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/dowhile_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/dowhile_fine.sol new file mode 100644 index 00000000..6520672c --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/dowhile_fine.sol @@ -0,0 +1,36 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S storage c) { + do {} while((c = s).f); + } + function g() internal view returns (S storage c) { + do { c = s; } while(false); + } + function h() internal view returns (S storage c) { + c = s; + do {} while(false); + } + function i() internal view returns (S storage c) { + do {} while(false); + c = s; + } + function j() internal view returns (S storage c) { + do { + c = s; + break; + } while(false); + } + function k() internal view returns (S storage c) { + do { + if (s.f) { + continue; + break; + } + else { + c = s; + } + } while(false); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/dowhile_warn.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/dowhile_warn.sol new file mode 100644 index 00000000..f1a92e9c --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/dowhile_warn.sol @@ -0,0 +1,35 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S storage c) { + do { + break; + c = s; + } while(false); + } + function g() internal view returns (S storage c) { + do { + if (s.f) { + continue; + c = s; + } + else { + } + } while(false); + } + function h() internal view returns (S storage c) { + do { + if (s.f) { + break; + continue; + } + else { + c = s; + } + } while(false); + } +} +// ---- +// Warning: (87-98): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (223-234): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (440-451): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/emptyReturn_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/emptyReturn_fine.sol new file mode 100644 index 00000000..3a0a30ea --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/emptyReturn_fine.sol @@ -0,0 +1,6 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S storage c, S storage d) { c = s; d = s; return; } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/emptyReturn_warn.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/emptyReturn_warn.sol new file mode 100644 index 00000000..0a5b2fbf --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/emptyReturn_warn.sol @@ -0,0 +1,15 @@ +contract C { + struct S { bool f; } + S s; + function f() internal pure returns (S storage) { return; } + function g() internal view returns (S storage c, S storage) { c = s; return; } + function h() internal view returns (S storage, S storage d) { d = s; return; } + function i() internal pure returns (S storage, S storage) { return; } + function j() internal view returns (S storage, S storage) { return (s,s); } +} +// ---- +// Warning: (87-88): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (163-164): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (233-234): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (316-317): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (327-328): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/for_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/for_fine.sol new file mode 100644 index 00000000..aa82cb9a --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/for_fine.sol @@ -0,0 +1,13 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S storage c) { + for(c = s;;) { + } + } + function g() internal view returns (S storage c) { + for(; (c = s).f;) { + } + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/for_warn.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/for_warn.sol new file mode 100644 index 00000000..ba9a2440 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/for_warn.sol @@ -0,0 +1,16 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S storage c) { + for(;; c = s) { + } + } + function g() internal view returns (S storage c) { + for(;;) { + c = s; + } + } +} +// ---- +// Warning: (87-98): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (182-193): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/if_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/if_fine.sol new file mode 100644 index 00000000..b809e95d --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/if_fine.sol @@ -0,0 +1,29 @@ +contract C { + struct S { bool f; } + S s; + function f(bool flag) internal view returns (S storage c) { + if (flag) c = s; + else c = s; + } + function g(bool flag) internal view returns (S storage c) { + if (flag) c = s; + else { c = s; } + } + function h(bool flag) internal view returns (S storage c) { + if (flag) c = s; + else + { + if (!flag) c = s; + else c = s; + } + } + function i() internal view returns (S storage c) { + if ((c = s).f) { + } + } + function j() internal view returns (S storage c) { + if ((c = s).f && !(c = s).f) { + } + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/if_warn.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/if_warn.sol new file mode 100644 index 00000000..c257c252 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/if_warn.sol @@ -0,0 +1,18 @@ +contract C { + struct S { bool f; } + S s; + function f(bool flag) internal view returns (S storage c) { + if (flag) c = s; + } + function g(bool flag) internal returns (S storage c) { + if (flag) c = s; + else + { + if (!flag) c = s; + else s.f = true; + } + } +} +// ---- +// Warning: (96-107): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (186-197): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/modifier_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/modifier_fine.sol new file mode 100644 index 00000000..ee37f6d6 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/modifier_fine.sol @@ -0,0 +1,20 @@ +contract C { + modifier revertIfNoReturn() { + _; + revert(); + } + modifier ifFlag(bool flag) { + if (flag) + _; + } + struct S { uint a; } + S s; + function f(bool flag) revertIfNoReturn() internal view returns(S storage) { + if (flag) return s; + } + function g(bool flag) revertIfNoReturn() ifFlag(flag) internal view returns(S storage) { + return s; + } + +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/modifier_warn.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/modifier_warn.sol new file mode 100644 index 00000000..50c6dd99 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/modifier_warn.sol @@ -0,0 +1,22 @@ +contract C { + modifier revertIfNoReturn() { + _; + revert(); + } + modifier ifFlag(bool flag) { + if (flag) + _; + } + struct S { uint a; } + S s; + function f(bool flag) ifFlag(flag) internal view returns(S storage) { + return s; + } + + function g(bool flag) ifFlag(flag) revertIfNoReturn() internal view returns(S storage) { + return s; + } +} +// ---- +// Warning: (249-250): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (367-368): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/revert_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/revert_fine.sol new file mode 100644 index 00000000..022f2d1c --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/revert_fine.sol @@ -0,0 +1,12 @@ +contract C { + struct S { bool f; } + S s; + function f() internal pure returns (S storage) { + revert(); + } + function g(bool flag) internal view returns (S storage c) { + if (flag) c = s; + else revert(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/short_circuit_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/short_circuit_fine.sol new file mode 100644 index 00000000..699849c0 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/short_circuit_fine.sol @@ -0,0 +1,11 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S storage c) { + (c = s).f && false; + } + function g() internal view returns (S storage c) { + (c = s).f || true; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/short_circuit_warn.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/short_circuit_warn.sol new file mode 100644 index 00000000..9f660f11 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/short_circuit_warn.sol @@ -0,0 +1,18 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S storage c) { + false && (c = s).f; + } + function g() internal view returns (S storage c) { + true || (c = s).f; + } + function h() internal view returns (S storage c) { + // expect warning, although this is always fine + true && (false || (c = s).f); + } +} +// ---- +// Warning: (87-98): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (176-187): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (264-275): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/smoke.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/smoke.sol new file mode 100644 index 00000000..beeadbe4 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/smoke.sol @@ -0,0 +1,10 @@ +contract C { + struct S { bool f; } + S s; + function f() internal pure {} + function g() internal view returns (S storage) { return s; } + function h() internal view returns (S storage c) { return s; } + function i() internal view returns (S storage c) { c = s; } + function j() internal view returns (S storage c) { (c) = s; } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/ternary_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/ternary_fine.sol new file mode 100644 index 00000000..ee3869bd --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/ternary_fine.sol @@ -0,0 +1,14 @@ +contract C { + struct S { bool f; } + S s; + function f(bool flag) internal view returns (S storage c) { + flag ? c = s : c = s; + } + function g(bool flag) internal view returns (S storage c) { + flag ? c = s : (c = s); + } + function h(bool flag) internal view returns (S storage c) { + flag ? (c = s).f : (c = s).f; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/ternary_warn.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/ternary_warn.sol new file mode 100644 index 00000000..57561fbb --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/ternary_warn.sol @@ -0,0 +1,13 @@ +contract C { + struct S { bool f; } + S s; + function f(bool flag) internal view returns (S storage c) { + flag ? (c = s).f : false; + } + function g(bool flag) internal view returns (S storage c) { + flag ? false : (c = s).f; + } +} +// ---- +// Warning: (96-107): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. +// Warning: (200-211): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/throw_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/throw_fine.sol new file mode 100644 index 00000000..4cecc27c --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/throw_fine.sol @@ -0,0 +1,9 @@ +contract C { + struct S { bool f; } + S s; + function f() internal pure returns (S storage) { + throw; + } +} +// ---- +// Warning: (108-113): "throw" is deprecated in favour of "revert()", "require()" and "assert()". diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/tuple_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/tuple_fine.sol new file mode 100644 index 00000000..0b171560 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/tuple_fine.sol @@ -0,0 +1,12 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S storage, uint) { + return (s,2); + } + function g() internal view returns (S storage c) { + uint a; + (c, a) = f(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/while_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/while_fine.sol new file mode 100644 index 00000000..71543422 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/while_fine.sol @@ -0,0 +1,19 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S storage c) { + while((c = s).f) { + } + } + function g() internal view returns (S storage c) { + c = s; + while(false) { + } + } + function h() internal view returns (S storage c) { + while(false) { + } + c = s; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/while_warn.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/while_warn.sol new file mode 100644 index 00000000..26db892f --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/while_warn.sol @@ -0,0 +1,11 @@ +contract C { + struct S { bool f; } + S s; + function f() internal view returns (S storage c) { + while(false) { + c = s; + } + } +} +// ---- +// Warning: (87-98): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol b/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol new file mode 100644 index 00000000..3571e8a9 --- /dev/null +++ b/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol @@ -0,0 +1,5 @@ +contract C { + uint constant x = 0x01 wei; +} +// ---- +// Warning: (32-40): Hexadecimal numbers with unit denominations are deprecated. You can use an expression of the form "0x1234 * 1 day" instead. diff --git a/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination_050.sol b/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination_050.sol new file mode 100644 index 00000000..98865999 --- /dev/null +++ b/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination_050.sol @@ -0,0 +1,6 @@ +pragma experimental "v0.5.0"; +contract C { + uint constant x = 0x01 wei; +} +// ---- +// TypeError: (62-70): Hexadecimal numbers cannot be used with unit denominations. You can use an expression of the form "0x1234 * 1 day" instead. diff --git a/test/libsolidity/syntaxTests/denominations/denominations.sol b/test/libsolidity/syntaxTests/denominations/denominations.sol new file mode 100644 index 00000000..6d1aa2f3 --- /dev/null +++ b/test/libsolidity/syntaxTests/denominations/denominations.sol @@ -0,0 +1,7 @@ +contract C { + uint constant a = 1 wei + 2 szabo + 3 finney + 4 ether; + uint constant b = 1 seconds + 2 minutes + 3 hours + 4 days + 5 weeks + 6 years; + uint constant c = 2 szabo / 1 seconds + 3 finney * 3 hours; +} +// ---- +// Warning: (142-149): Using "years" as a unit denomination is deprecated. diff --git a/test/libsolidity/syntaxTests/denominations/deprecated_year.sol b/test/libsolidity/syntaxTests/denominations/deprecated_year.sol new file mode 100644 index 00000000..30e86535 --- /dev/null +++ b/test/libsolidity/syntaxTests/denominations/deprecated_year.sol @@ -0,0 +1,5 @@ +contract C { + uint constant a = 3 years; +} +// ---- +// Warning: (32-39): Using "years" as a unit denomination is deprecated. diff --git a/test/libsolidity/syntaxTests/denominations/deprecated_year_050.sol b/test/libsolidity/syntaxTests/denominations/deprecated_year_050.sol new file mode 100644 index 00000000..4baaeaa3 --- /dev/null +++ b/test/libsolidity/syntaxTests/denominations/deprecated_year_050.sol @@ -0,0 +1,6 @@ +pragma experimental "v0.5.0"; +contract C { + uint constant a = 3 years; +} +// ---- +// TypeError: (62-69): Using "years" as a unit denomination is deprecated. diff --git a/test/libsolidity/syntaxTests/denominations/fixed_point_division.sol b/test/libsolidity/syntaxTests/denominations/fixed_point_division.sol new file mode 100644 index 00000000..22331b51 --- /dev/null +++ b/test/libsolidity/syntaxTests/denominations/fixed_point_division.sol @@ -0,0 +1,6 @@ +contract C { + uint constant a = 4 ether / 3 hours; + ufixed constant b = ufixed(4 ether / 3 hours); +} +// ---- +// TypeError: (32-49): Type rational_const 10000000000000000 / 27 is not implicitly convertible to expected type uint256. Try converting to type ufixed256x62 or use an explicit conversion. diff --git a/test/libsolidity/syntaxTests/deprecated_functions.sol b/test/libsolidity/syntaxTests/deprecated_functions.sol new file mode 100644 index 00000000..57ee484a --- /dev/null +++ b/test/libsolidity/syntaxTests/deprecated_functions.sol @@ -0,0 +1,12 @@ +contract test { + function f() pure public { + bytes32 x = sha3(uint8(1)); + x; + } + function g() public { + suicide(1); + } +} +// ---- +// Warning: (58-72): "sha3" has been deprecated in favour of "keccak256" +// Warning: (107-117): "suicide" has been deprecated in favour of "selfdestruct" diff --git a/test/libsolidity/syntaxTests/deprecated_functions_050.sol b/test/libsolidity/syntaxTests/deprecated_functions_050.sol new file mode 100644 index 00000000..7e36543b --- /dev/null +++ b/test/libsolidity/syntaxTests/deprecated_functions_050.sol @@ -0,0 +1,13 @@ +pragma experimental "v0.5.0"; +contract test { + function f() pure public { + bytes32 x = sha3(uint8(1)); + x; + } + function g() public { + suicide(1); + } +} +// ---- +// TypeError: (88-102): "sha3" has been deprecated in favour of "keccak256" +// TypeError: (137-147): "suicide" has been deprecated in favour of "selfdestruct" diff --git a/test/libsolidity/syntaxTests/emit_non_event.sol b/test/libsolidity/syntaxTests/emit_non_event.sol new file mode 100644 index 00000000..1df6990d --- /dev/null +++ b/test/libsolidity/syntaxTests/emit_non_event.sol @@ -0,0 +1,10 @@ +contract C { + uint256 Test; + + function f() { + emit Test(); + } +} +// ---- +// TypeError: (56-62): Type is not callable +// TypeError: (56-60): Expression has to be an event invocation. diff --git a/test/libsolidity/syntaxTests/empty_string_var.sol b/test/libsolidity/syntaxTests/empty_string_var.sol new file mode 100644 index 00000000..e9837590 --- /dev/null +++ b/test/libsolidity/syntaxTests/empty_string_var.sol @@ -0,0 +1,11 @@ +contract C { + function f() { + var a = ""; + bytes1 b = bytes1(a); + bytes memory c = bytes(a); + string memory d = string(a); + } +} +// ---- +// Warning: (34-39): Use of the "var" keyword is deprecated. +// TypeError: (61-70): Explicit type conversion not allowed from "string memory" to "bytes1". diff --git a/test/libsolidity/syntaxTests/fallback/pure_modifier.sol b/test/libsolidity/syntaxTests/fallback/pure_modifier.sol new file mode 100644 index 00000000..20d5b0ac --- /dev/null +++ b/test/libsolidity/syntaxTests/fallback/pure_modifier.sol @@ -0,0 +1,6 @@ +contract C { + uint x; + function() pure { x = 2; } +} +// ---- +// TypeError: (29-55): Fallback function must be payable or non-payable, but is "pure". diff --git a/test/libsolidity/syntaxTests/fallback/view_modifier.sol b/test/libsolidity/syntaxTests/fallback/view_modifier.sol new file mode 100644 index 00000000..44c5d204 --- /dev/null +++ b/test/libsolidity/syntaxTests/fallback/view_modifier.sol @@ -0,0 +1,6 @@ +contract C { + uint x; + function() view { x = 2; } +} +// ---- +// TypeError: (29-55): Fallback function must be payable or non-payable, but is "view". diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol index b7763d28..b89a3bb4 100644 --- a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol @@ -5,4 +5,4 @@ contract C { } } // ---- -// ParserError: (118-118): Expected token Semicolon got 'Identifier' +// ParserError: (118-119): Expected ';' but got identifier diff --git a/test/libsolidity/syntaxTests/inheritance/override/add_view.sol b/test/libsolidity/syntaxTests/inheritance/override/add_view.sol new file mode 100644 index 00000000..9973b23e --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/add_view.sol @@ -0,0 +1,4 @@ +contract B { function f() public {} } +contract C is B { function f() view {} } +// ---- +// TypeError: (56-76): Overriding function changes state mutability from "nonpayable" to "view". diff --git a/test/libsolidity/syntaxTests/inheritance/override/remove_view.sol b/test/libsolidity/syntaxTests/inheritance/override/remove_view.sol new file mode 100644 index 00000000..e58f6b20 --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/remove_view.sol @@ -0,0 +1,4 @@ +contract B { function f() view {} } +contract C is B { function f() public {} } +// ---- +// TypeError: (54-76): Overriding function changes state mutability from "view" to "nonpayable". diff --git a/test/libsolidity/syntaxTests/missing_state_variable.sol b/test/libsolidity/syntaxTests/missing_state_variable.sol new file mode 100644 index 00000000..02082a45 --- /dev/null +++ b/test/libsolidity/syntaxTests/missing_state_variable.sol @@ -0,0 +1,7 @@ +contract Scope { + function getStateVar() view public returns (uint stateVar) { + stateVar = Scope.stateVar; // should fail. + } +} +// ---- +// TypeError: (101-115): Member "stateVar" not found or not visible after argument-dependent lookup in type(contract Scope) diff --git a/test/libsolidity/syntaxTests/docstring_empty_description.sol b/test/libsolidity/syntaxTests/natspec/docstring_empty_description.sol index 0caa1b23..0caa1b23 100644 --- a/test/libsolidity/syntaxTests/docstring_empty_description.sol +++ b/test/libsolidity/syntaxTests/natspec/docstring_empty_description.sol diff --git a/test/libsolidity/syntaxTests/natspec/docstring_empty_tag.sol b/test/libsolidity/syntaxTests/natspec/docstring_empty_tag.sol new file mode 100644 index 00000000..9a28143a --- /dev/null +++ b/test/libsolidity/syntaxTests/natspec/docstring_empty_tag.sol @@ -0,0 +1,6 @@ +contract C { + /// @param + function vote(uint id) public; +} +// ---- +// DocstringParsingError: End of tag @param not found diff --git a/test/libsolidity/syntaxTests/parsing/constant_is_keyword.sol b/test/libsolidity/syntaxTests/parsing/constant_is_keyword.sol new file mode 100644 index 00000000..26d126ce --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/constant_is_keyword.sol @@ -0,0 +1,5 @@ +contract Foo { + uint constant = 4; +} +// ---- +// ParserError: (30-31): Expected identifier but got '=' diff --git a/test/libsolidity/syntaxTests/parsing/constant_state_modifier.sol b/test/libsolidity/syntaxTests/parsing/constant_state_modifier.sol new file mode 100644 index 00000000..da068351 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/constant_state_modifier.sol @@ -0,0 +1,7 @@ +contract C { + uint s; + // this test should fail starting from 0.5.0 + function f() public constant returns (uint) { + return s; + } +} diff --git a/test/libsolidity/syntaxTests/parsing/emit_without_event.sol b/test/libsolidity/syntaxTests/parsing/emit_without_event.sol new file mode 100644 index 00000000..b838b4af --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/emit_without_event.sol @@ -0,0 +1,8 @@ +contract C { + event A(); + function f() { + emit A; + } +} +// ---- +// ParserError: (49-50): Expected '(' but got ';' diff --git a/test/libsolidity/syntaxTests/parsing/empty_enum.sol b/test/libsolidity/syntaxTests/parsing/empty_enum.sol new file mode 100644 index 00000000..483f6a91 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/empty_enum.sol @@ -0,0 +1,5 @@ +contract c { + enum foo { } +} +// ---- +// ParserError: (25-26): enum with no members is not allowed. diff --git a/test/libsolidity/syntaxTests/parsing/empty_function.sol b/test/libsolidity/syntaxTests/parsing/empty_function.sol new file mode 100644 index 00000000..218fd9a7 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/empty_function.sol @@ -0,0 +1,10 @@ +contract test { + uint256 stateVar; + function functionName(bytes20 arg1, address addr) view returns (int id) { } +} +// ---- +// Warning: (36-111): No visibility specified. Defaulting to "public". +// Warning: (58-70): Unused function parameter. Remove or comment out the variable name to silence this warning. +// Warning: (72-84): Unused function parameter. Remove or comment out the variable name to silence this warning. +// Warning: (100-106): Unused function parameter. Remove or comment out the variable name to silence this warning. +// Warning: (36-111): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/parsing/event_with_no_argument_list.sol b/test/libsolidity/syntaxTests/parsing/event_with_no_argument_list.sol new file mode 100644 index 00000000..b38c7dc9 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/event_with_no_argument_list.sol @@ -0,0 +1,5 @@ +contract c { + event e; +} +// ---- +// ParserError: (21-22): Expected '(' but got ';' diff --git a/test/libsolidity/syntaxTests/parsing/external_variable.sol b/test/libsolidity/syntaxTests/parsing/external_variable.sol new file mode 100644 index 00000000..2a02d19a --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/external_variable.sol @@ -0,0 +1,5 @@ +contract c { + uint external x; +} +// ---- +// ParserError: (19-27): Expected identifier but got 'external' diff --git a/test/libsolidity/syntaxTests/parsing/fixed_literal_with_double_radix.sol b/test/libsolidity/syntaxTests/parsing/fixed_literal_with_double_radix.sol new file mode 100644 index 00000000..0d5734aa --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/fixed_literal_with_double_radix.sol @@ -0,0 +1,5 @@ +contract A { + fixed40x40 pi = 3.14.15; +} +// ---- +// ParserError: (34-37): Expected ';' but got 'Number' diff --git a/test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable_with_modifiers.sol b/test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable_with_modifiers.sol new file mode 100644 index 00000000..6c22f4b7 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable_with_modifiers.sol @@ -0,0 +1,5 @@ +contract test { + function (uint, uint) modifier1() returns (uint) f1; +} +// ---- +// ParserError: (66-68): Expected '{' but got identifier diff --git a/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_lvalue.sol b/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_lvalue.sol new file mode 100644 index 00000000..9460751c --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_lvalue.sol @@ -0,0 +1,9 @@ +contract c { + uint[] a; + function f() returns (uint) { + a = [,2,3]; + return (a[0]); + } +} +// ---- +// ParserError: (62-63): Expected expression (inline array elements cannot be omitted). diff --git a/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_without_lvalue.sol b/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_without_lvalue.sol new file mode 100644 index 00000000..5b78232d --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_without_lvalue.sol @@ -0,0 +1,8 @@ +contract c { + uint[] a; + function f() returns (uint, uint) { + return ([3, ,4][0]); + } +} +// ---- +// ParserError: (75-76): Expected expression (inline array elements cannot be omitted). diff --git a/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol b/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol new file mode 100644 index 00000000..fb267ba3 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol @@ -0,0 +1,7 @@ +contract test { + function f() { + fixed a = 1.0x2; + } +} +// ---- +// ParserError: (44-47): Expected primary expression. diff --git a/test/libsolidity/syntaxTests/parsing/local_const_variable.sol b/test/libsolidity/syntaxTests/parsing/local_const_variable.sol new file mode 100644 index 00000000..505fe0b5 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/local_const_variable.sol @@ -0,0 +1,9 @@ +contract Foo { + function localConst() returns (uint ret) + { + uint constant local = 4; + return local; + } +} +// ---- +// ParserError: (67-75): Expected ';' but got 'constant' diff --git a/test/libsolidity/syntaxTests/parsing/location_specifiers_for_state_variables.sol b/test/libsolidity/syntaxTests/parsing/location_specifiers_for_state_variables.sol new file mode 100644 index 00000000..40eaf838 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/location_specifiers_for_state_variables.sol @@ -0,0 +1,5 @@ +contract Foo { + uint[] memory x; +} +// ---- +// ParserError: (23-29): Expected identifier but got 'memory' diff --git a/test/libsolidity/syntaxTests/parsing/location_specifiers_with_var.sol b/test/libsolidity/syntaxTests/parsing/location_specifiers_with_var.sol new file mode 100644 index 00000000..2b8f08c5 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/location_specifiers_with_var.sol @@ -0,0 +1,5 @@ +contract Foo { + function f() { var memory x; } +} +// ---- +// ParserError: (35-41): Location specifier needs explicit type name. diff --git a/test/libsolidity/syntaxTests/parsing/malformed_enum_declaration.sol b/test/libsolidity/syntaxTests/parsing/malformed_enum_declaration.sol new file mode 100644 index 00000000..811b4219 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/malformed_enum_declaration.sol @@ -0,0 +1,5 @@ +contract c { + enum foo { WARNING,} +} +// ---- +// ParserError: (33-34): Expected identifier after ',' diff --git a/test/libsolidity/syntaxTests/parsing/missing_argument_in_named_args.sol b/test/libsolidity/syntaxTests/parsing/missing_argument_in_named_args.sol new file mode 100644 index 00000000..f7c3fb31 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/missing_argument_in_named_args.sol @@ -0,0 +1,6 @@ +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: }); } +} +// ---- +// ParserError: (146-147): Expected primary expression. diff --git a/test/libsolidity/syntaxTests/parsing/missing_parameter_name_in_named_args.sol b/test/libsolidity/syntaxTests/parsing/missing_parameter_name_in_named_args.sol new file mode 100644 index 00000000..d7c2f2be --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/missing_parameter_name_in_named_args.sol @@ -0,0 +1,6 @@ +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}); } +} +// ---- +// ParserError: (143-144): Expected identifier but got ':' diff --git a/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol b/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol index fd3067e3..51b7bd24 100644 --- a/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol +++ b/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol @@ -2,4 +2,4 @@ contract test { uint256 ; } // ---- -// ParserError: (28-28): Expected identifier, got 'Semicolon' +// ParserError: (28-29): Expected identifier but got ';' diff --git a/test/libsolidity/syntaxTests/parsing/modifier_without_semicolon.sol b/test/libsolidity/syntaxTests/parsing/modifier_without_semicolon.sol new file mode 100644 index 00000000..a9fa33e6 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/modifier_without_semicolon.sol @@ -0,0 +1,5 @@ +contract c { + modifier mod { if (msg.sender == 0) _ } +} +// ---- +// ParserError: (52-53): Expected ';' but got '}' diff --git a/test/libsolidity/syntaxTests/parsing/multiple_statemutability_specifiers.sol b/test/libsolidity/syntaxTests/parsing/multiple_statemutability_specifiers.sol new file mode 100644 index 00000000..a05bf452 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/multiple_statemutability_specifiers.sol @@ -0,0 +1,33 @@ +contract c1 { + function f() payable payable {} +} +contract c2 { + function f() view view {} +} +contract c3 { + function f() pure pure {} +} +contract c4 { + function f() pure view {} +} +contract c5 { + function f() payable view {} +} +contract c6 { + function f() pure payable {} +} +contract c7 { + function f() pure constant {} +} +contract c8 { + function f() view constant {} +} +// ---- +// ParserError: (39-46): State mutability already specified as "payable". +// ParserError: (88-92): State mutability already specified as "view". +// ParserError: (134-138): State mutability already specified as "pure". +// ParserError: (180-184): State mutability already specified as "pure". +// ParserError: (229-233): State mutability already specified as "payable". +// ParserError: (275-282): State mutability already specified as "pure". +// ParserError: (324-332): State mutability already specified as "pure". +// ParserError: (374-382): State mutability already specified as "view". diff --git a/test/libsolidity/syntaxTests/parsing/new_invalid_type_name.sol b/test/libsolidity/syntaxTests/parsing/new_invalid_type_name.sol new file mode 100644 index 00000000..d469bc75 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/new_invalid_type_name.sol @@ -0,0 +1,7 @@ +contract C { + function f() { + new var; + } +} +// ---- +// ParserError: (35-38): Expected explicit type name. diff --git a/test/libsolidity/syntaxTests/parsing/no_function_params.sol b/test/libsolidity/syntaxTests/parsing/no_function_params.sol new file mode 100644 index 00000000..020f1233 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/no_function_params.sol @@ -0,0 +1,7 @@ +contract test { + uint256 stateVar; + function functionName() {} +} +// ---- +// Warning: (36-62): No visibility specified. Defaulting to "public". +// Warning: (36-62): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/parsing/payable_accessor.sol b/test/libsolidity/syntaxTests/parsing/payable_accessor.sol new file mode 100644 index 00000000..6504004b --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/payable_accessor.sol @@ -0,0 +1,5 @@ +contract test { + uint payable x; +} +// ---- +// ParserError: (22-29): Expected identifier but got 'payable' diff --git a/test/libsolidity/syntaxTests/parsing/return_var.sol b/test/libsolidity/syntaxTests/parsing/return_var.sol index 47ac9ef0..b9ce8f95 100644 --- a/test/libsolidity/syntaxTests/parsing/return_var.sol +++ b/test/libsolidity/syntaxTests/parsing/return_var.sol @@ -9,17 +9,17 @@ contract C { function f() public pure returns (var storage x, var storage y) {} } // ---- -// ParserError: (38-38): Expected explicit type name. -// ParserError: (71-71): Expected explicit type name. -// ParserError: (106-106): Expected explicit type name. -// ParserError: (157-157): Expected explicit type name. -// ParserError: (192-192): Expected explicit type name. -// ParserError: (199-199): Expected explicit type name. -// ParserError: (247-247): Expected explicit type name. -// ParserError: (251-251): Location specifier needs explicit type name. -// ParserError: (301-301): Expected explicit type name. -// ParserError: (305-305): Location specifier needs explicit type name. -// ParserError: (357-357): Expected explicit type name. -// ParserError: (361-361): Location specifier needs explicit type name. -// ParserError: (372-372): Expected explicit type name. -// ParserError: (376-376): Location specifier needs explicit type name. +// ParserError: (38-41): Expected explicit type name. +// ParserError: (71-74): Expected explicit type name. +// ParserError: (106-109): Expected explicit type name. +// ParserError: (157-160): Expected explicit type name. +// ParserError: (192-195): Expected explicit type name. +// ParserError: (199-202): Expected explicit type name. +// ParserError: (247-250): Expected explicit type name. +// ParserError: (251-258): Location specifier needs explicit type name. +// ParserError: (301-304): Expected explicit type name. +// ParserError: (305-312): Location specifier needs explicit type name. +// ParserError: (357-360): Expected explicit type name. +// ParserError: (361-368): Location specifier needs explicit type name. +// ParserError: (372-375): Expected explicit type name. +// ParserError: (376-383): Location specifier needs explicit type name. diff --git a/test/libsolidity/syntaxTests/parsing/scientific_notation.sol b/test/libsolidity/syntaxTests/parsing/scientific_notation.sol new file mode 100644 index 00000000..5d656508 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/scientific_notation.sol @@ -0,0 +1,7 @@ +contract test { + uint256 a = 2e10; + uint256 b = 2E10; + uint256 c = 200e-2; + uint256 d = 2E10 wei; + uint256 e = 2.5e10; +} diff --git a/test/libsolidity/syntaxTests/parsing/single_function_param.sol b/test/libsolidity/syntaxTests/parsing/single_function_param.sol new file mode 100644 index 00000000..08e531f1 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/single_function_param.sol @@ -0,0 +1,9 @@ +contract test { + uint256 stateVar; + function functionName(bytes32 input) returns (bytes32 out) {} +} +// ---- +// Warning: (36-97): No visibility specified. Defaulting to "public". +// Warning: (58-71): Unused function parameter. Remove or comment out the variable name to silence this warning. +// Warning: (82-93): Unused function parameter. Remove or comment out the variable name to silence this warning. +// Warning: (36-97): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/parsing/single_function_param_trailing_comma.sol b/test/libsolidity/syntaxTests/parsing/single_function_param_trailing_comma.sol new file mode 100644 index 00000000..fe52b3b2 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/single_function_param_trailing_comma.sol @@ -0,0 +1,5 @@ +contract test { + function(uint a,) {} +} +// ---- +// ParserError: (32-33): Unexpected trailing comma in parameter list. diff --git a/test/libsolidity/syntaxTests/parsing/single_return_param_trailing_comma.sol b/test/libsolidity/syntaxTests/parsing/single_return_param_trailing_comma.sol new file mode 100644 index 00000000..99f91819 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/single_return_param_trailing_comma.sol @@ -0,0 +1,5 @@ +contract test { + function() returns (uint a,) {} +} +// ---- +// ParserError: (43-44): Unexpected trailing comma in parameter list. diff --git a/test/libsolidity/syntaxTests/parsing/trailing_comma_in_named_args.sol b/test/libsolidity/syntaxTests/parsing/trailing_comma_in_named_args.sol new file mode 100644 index 00000000..8fc3dab8 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/trailing_comma_in_named_args.sol @@ -0,0 +1,6 @@ +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, }); } +} +// ---- +// ParserError: (159-160): Unexpected trailing comma. diff --git a/test/libsolidity/syntaxTests/parsing/tuples_without_commas.sol b/test/libsolidity/syntaxTests/parsing/tuples_without_commas.sol new file mode 100644 index 00000000..fcbb875c --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/tuples_without_commas.sol @@ -0,0 +1,7 @@ +contract C { + function f() { + var a = (2 2); + } +} +// ---- +// ParserError: (42-43): Expected ',' but got 'Number' diff --git a/test/libsolidity/syntaxTests/parsing/var_array.sol b/test/libsolidity/syntaxTests/parsing/var_array.sol new file mode 100644 index 00000000..e08f5511 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/var_array.sol @@ -0,0 +1,5 @@ +contract Foo { + function f() { var[] a; } +} +// ---- +// ParserError: (34-35): Expected identifier but got '[' diff --git a/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol b/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol index e041247d..2e5a9c58 100644 --- a/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol +++ b/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol @@ -9,17 +9,17 @@ contract C { function f(var storage x, var storage y) public pure {} } // ---- -// ParserError: (28-28): Expected explicit type name. -// ParserError: (63-63): Expected explicit type name. -// ParserError: (100-100): Expected explicit type name. -// ParserError: (107-107): Expected explicit type name. -// ParserError: (152-152): Expected explicit type name. -// ParserError: (189-189): Expected explicit type name. -// ParserError: (234-234): Expected explicit type name. -// ParserError: (238-238): Location specifier needs explicit type name. -// ParserError: (277-277): Expected explicit type name. -// ParserError: (281-281): Location specifier needs explicit type name. -// ParserError: (322-322): Expected explicit type name. -// ParserError: (326-326): Location specifier needs explicit type name. -// ParserError: (337-337): Expected explicit type name. -// ParserError: (341-341): Location specifier needs explicit type name. +// ParserError: (28-31): Expected explicit type name. +// ParserError: (63-66): Expected explicit type name. +// ParserError: (100-103): Expected explicit type name. +// ParserError: (107-110): Expected explicit type name. +// ParserError: (152-155): Expected explicit type name. +// ParserError: (189-192): Expected explicit type name. +// ParserError: (234-237): Expected explicit type name. +// ParserError: (238-245): Location specifier needs explicit type name. +// ParserError: (277-280): Expected explicit type name. +// ParserError: (281-288): Location specifier needs explicit type name. +// ParserError: (322-325): Expected explicit type name. +// ParserError: (326-333): Location specifier needs explicit type name. +// ParserError: (337-340): Expected explicit type name. +// ParserError: (341-348): Location specifier needs explicit type name. diff --git a/test/libsolidity/syntaxTests/parsing/var_storage_var.sol b/test/libsolidity/syntaxTests/parsing/var_storage_var.sol index 431d4ca5..6e4ccfa5 100644 --- a/test/libsolidity/syntaxTests/parsing/var_storage_var.sol +++ b/test/libsolidity/syntaxTests/parsing/var_storage_var.sol @@ -2,4 +2,4 @@ contract C { var a; } // ---- -// ParserError: (17-17): Function, variable, struct or modifier declaration expected. +// ParserError: (17-20): Function, variable, struct or modifier declaration expected. diff --git a/test/libsolidity/syntaxTests/parsing/variable_definition_in_mapping.sol b/test/libsolidity/syntaxTests/parsing/variable_definition_in_mapping.sol new file mode 100644 index 00000000..61f5be53 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/variable_definition_in_mapping.sol @@ -0,0 +1,7 @@ +contract test { + function fun() { + mapping(var=>bytes32) d; + } +} +// ---- +// ParserError: (44-47): Expected elementary type name for mapping key type diff --git a/test/libsolidity/syntaxTests/tight_packing_literals_050.sol b/test/libsolidity/syntaxTests/tight_packing_literals_050.sol new file mode 100644 index 00000000..ef6da75d --- /dev/null +++ b/test/libsolidity/syntaxTests/tight_packing_literals_050.sol @@ -0,0 +1,26 @@ +pragma experimental "v0.5.0"; +contract C { + function f() pure public returns (bytes32) { + return keccak256(1); + } + function g() pure public returns (bytes32) { + return sha3(1); + } + function h() pure public returns (bytes32) { + return sha256(1); + } + function j() pure public returns (bytes32) { + return ripemd160(1); + } + function k() pure public returns (bytes) { + return abi.encodePacked(1); + } +} + +// ---- +// TypeError: (117-118): Cannot perform packed encoding for a literal. Please convert it to an explicit type first. +// TypeError: (191-198): "sha3" has been deprecated in favour of "keccak256" +// TypeError: (196-197): Cannot perform packed encoding for a literal. Please convert it to an explicit type first. +// TypeError: (277-278): Cannot perform packed encoding for a literal. Please convert it to an explicit type first. +// TypeError: (361-362): Cannot perform packed encoding for a literal. Please convert it to an explicit type first. +// TypeError: (450-451): Cannot perform packed encoding for a literal. Please convert it to an explicit type first. diff --git a/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol b/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol index 46407f71..81e69eb4 100644 --- a/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol +++ b/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol @@ -2,10 +2,21 @@ contract C { function f() pure public returns (bytes32) { return keccak256(uint8(1)); } - function g() pure public returns (bytes) { - return abi.encode(1); + function g() pure public returns (bytes32) { + return sha3(uint8(1)); + } + function h() pure public returns (bytes32) { + return sha256(uint8(1)); + } + function j() pure public returns (bytes32) { + return ripemd160(uint8(1)); } - function h() pure public returns (bytes) { + function k() pure public returns (bytes) { return abi.encodePacked(uint8(1)); } + function l() pure public returns (bytes) { + return abi.encode(1); + } } +// ---- +// Warning: (168-182): "sha3" has been deprecated in favour of "keccak256" diff --git a/test/libsolidity/syntaxTests/tupleAssignments/error_fill.sol b/test/libsolidity/syntaxTests/tupleAssignments/error_fill.sol new file mode 100644 index 00000000..5b7f870b --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/error_fill.sol @@ -0,0 +1,12 @@ +pragma experimental "v0.5.0"; +contract C { + function f() public pure returns (uint, uint, bytes32) { + uint a; + bytes32 b; + (a,) = f(); + (,b) = f(); + } +} +// ---- +// TypeError: (126-136): Different number of components on the left hand side (2) than on the right hand side (3). +// TypeError: (140-150): Different number of components on the left hand side (2) than on the right hand side (3). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/large_component_count.sol b/test/libsolidity/syntaxTests/tupleAssignments/large_component_count.sol new file mode 100644 index 00000000..bbf21d7e --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/large_component_count.sol @@ -0,0 +1,24 @@ +pragma experimental "v0.5.0"; +contract C { + function g() public pure returns ( + uint, + uint, + uint, + uint, + uint, + uint, + uint, + uint, + uint, + uint, + uint, + uint, + uint + ) { } + function f() public pure returns (uint, uint, bytes32) { + uint a; + uint b; + (,,,,a,,,,b,,,,) = g(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/tupleAssignments/nowarn_explicit_singleton_token_expression.sol b/test/libsolidity/syntaxTests/tupleAssignments/nowarn_explicit_singleton_token_expression.sol new file mode 100644 index 00000000..3262781b --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/nowarn_explicit_singleton_token_expression.sol @@ -0,0 +1,8 @@ +contract C { + function f() public pure { + uint a; + (a,) = (uint(1),); + } +} +// ---- +// Warning: (53-70): Different number of components on the left hand side (2) than on the right hand side (1). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/nowarn_swap_memory.sol b/test/libsolidity/syntaxTests/tupleAssignments/nowarn_swap_memory.sol new file mode 100644 index 00000000..b20bbf90 --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/nowarn_swap_memory.sol @@ -0,0 +1,8 @@ +contract C { + struct S { uint a; uint b; } + function f() pure public { + S memory x; + S memory y; + (x, y) = (y, x); + } +} diff --git a/test/libsolidity/syntaxTests/tupleAssignments/nowarn_swap_storage_pointers.sol b/test/libsolidity/syntaxTests/tupleAssignments/nowarn_swap_storage_pointers.sol new file mode 100644 index 00000000..5f7a18f7 --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/nowarn_swap_storage_pointers.sol @@ -0,0 +1,10 @@ + contract C { + struct S { uint a; uint b; } + S x; S y; + function f() public { + S storage x_local = x; + S storage y_local = y; + S storage z_local = x; + (x, y_local, x_local, z_local) = (y, x_local, y_local, y); + } + } diff --git a/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_assignment.sol b/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_assignment.sol new file mode 100644 index 00000000..a079a509 --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_assignment.sol @@ -0,0 +1,11 @@ +contract C { + function f() public pure returns (uint, uint, bytes32) { + uint a; + bytes32 b; + (a,) = f(); + (,b) = f(); + } +} +// ---- +// Warning: (96-106): Different number of components on the left hand side (2) than on the right hand side (3). +// Warning: (110-120): Different number of components on the left hand side (2) than on the right hand side (3). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_vardecl.sol b/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_vardecl.sol new file mode 100644 index 00000000..1d243c7c --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_vardecl.sol @@ -0,0 +1,11 @@ +contract C { + function f() public pure returns (uint, uint, uint, uint) { + // Can later be replaced by (uint a, uint b,) = f(); + var (a,b,) = f(); + a; b; + } +} +// ---- +// Warning: (136-137): Use of the "var" keyword is deprecated. +// Warning: (138-139): Use of the "var" keyword is deprecated. +// Warning: (131-147): Different number of components on the left hand side (3) than on the right hand side (4). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies.sol b/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies.sol new file mode 100644 index 00000000..e4c3e694 --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies.sol @@ -0,0 +1,9 @@ +contract C { + struct S { uint a; uint b; } + S x; S y; + function f() public { + (x, y) = (y, x); + } +} +// ---- +// Warning: (79-94): This assignment performs two copies to storage. Since storage copies do not first copy to a temporary location, one of them might be overwritten before the second is executed and thus may have unexpected effects. It is safer to perform the copies separately or assign to storage pointers first. diff --git a/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies_fill_left.sol b/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies_fill_left.sol new file mode 100644 index 00000000..b2979804 --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies_fill_left.sol @@ -0,0 +1,10 @@ +contract C { + struct S { uint a; uint b; } + S x; S y; + function f() public { + (,x, y) = (1, 2, y, x); + } +} +// ---- +// Warning: (79-101): This assignment performs two copies to storage. Since storage copies do not first copy to a temporary location, one of them might be overwritten before the second is executed and thus may have unexpected effects. It is safer to perform the copies separately or assign to storage pointers first. +// Warning: (79-101): Different number of components on the left hand side (3) than on the right hand side (4). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies_fill_right.sol b/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies_fill_right.sol new file mode 100644 index 00000000..aa35d7d4 --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies_fill_right.sol @@ -0,0 +1,10 @@ +contract C { + struct S { uint a; uint b; } + S x; S y; + function f() public { + (x, y, ) = (y, x, 1, 2); + } +} +// ---- +// Warning: (79-102): This assignment performs two copies to storage. Since storage copies do not first copy to a temporary location, one of them might be overwritten before the second is executed and thus may have unexpected effects. It is safer to perform the copies separately or assign to storage pointers first. +// Warning: (79-102): Different number of components on the left hand side (3) than on the right hand side (4). diff --git a/test/libsolidity/syntaxTests/types/bytes0.sol b/test/libsolidity/syntaxTests/types/bytes0.sol new file mode 100644 index 00000000..7c6d5974 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/bytes0.sol @@ -0,0 +1,5 @@ +contract C { + bytes0 b0 = 1; +} +// ---- +// DeclarationError: (15-21): Identifier not found or not unique. diff --git a/test/libsolidity/syntaxTests/types/bytes256.sol b/test/libsolidity/syntaxTests/types/bytes256.sol new file mode 100644 index 00000000..22b5408d --- /dev/null +++ b/test/libsolidity/syntaxTests/types/bytes256.sol @@ -0,0 +1,5 @@ +contract C { + bytes256 b256 = 1; +} +// ---- +// DeclarationError: (15-23): Identifier not found or not unique. diff --git a/test/libsolidity/syntaxTests/types/bytes33.sol b/test/libsolidity/syntaxTests/types/bytes33.sol new file mode 100644 index 00000000..7edf13d3 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/bytes33.sol @@ -0,0 +1,5 @@ +contract C { + bytes33 b33 = 1; +} +// ---- +// DeclarationError: (15-22): Identifier not found or not unique. diff --git a/test/libsolidity/syntaxTests/types/bytesm.sol b/test/libsolidity/syntaxTests/types/bytesm.sol new file mode 100644 index 00000000..550760b9 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/bytesm.sol @@ -0,0 +1,36 @@ +contract C { + byte b = byte(1); + bytes1 b1 = b; + bytes2 b2 = b1; + bytes3 b3 = b2; + bytes4 b4 = b3; + bytes5 b5 = b4; + bytes6 b6 = b5; + bytes7 b7 = b6; + bytes8 b8 = b7; + bytes9 b9 = b8; + bytes10 b10 = b9; + bytes11 b11 = b10; + bytes12 b12 = b11; + bytes13 b13 = b12; + bytes14 b14 = b13; + bytes15 b15 = b14; + bytes16 b16 = b15; + bytes17 b17 = b16; + bytes18 b18 = b17; + bytes19 b19 = b18; + bytes20 b20 = b19; + bytes21 b21 = b20; + bytes22 b22 = b21; + bytes23 b23 = b22; + bytes24 b24 = b23; + bytes25 b25 = b24; + bytes26 b26 = b25; + bytes27 b27 = b26; + bytes28 b28 = b27; + bytes29 b29 = b28; + bytes30 b30 = b29; + bytes31 b31 = b30; + bytes32 b32 = b31; +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_event.sol b/test/libsolidity/syntaxTests/types/empty_tuple_event.sol new file mode 100644 index 00000000..3e40b155 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/empty_tuple_event.sol @@ -0,0 +1,10 @@ +pragma solidity ^0.4.3; +contract C { + event SomeEvent(); + function a() public { + (SomeEvent(), 7); + } +} +// ---- +// Warning: (95-106): Invoking events without "emit" prefix is deprecated. +// Warning: (95-106): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_event_050.sol b/test/libsolidity/syntaxTests/types/empty_tuple_event_050.sol new file mode 100644 index 00000000..aec5ff2a --- /dev/null +++ b/test/libsolidity/syntaxTests/types/empty_tuple_event_050.sol @@ -0,0 +1,10 @@ +pragma experimental "v0.5.0"; +contract C { + event SomeEvent(); + function a() public { + (SomeEvent(), 7); + } +} +// ---- +// TypeError: (101-112): Event invocations have to be prefixed by "emit". +// TypeError: (101-112): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_function.sol b/test/libsolidity/syntaxTests/types/empty_tuple_function.sol new file mode 100644 index 00000000..05b54442 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/empty_tuple_function.sol @@ -0,0 +1,12 @@ +pragma solidity ^0.4.3; +contract C { + function f() private pure {} + function a() public pure { + bool x = true; + bool y = true; + (x) ? (f(), y = false) : (f(), y = false); + } +} +// ---- +// Warning: (162-165): Tuple component cannot be empty. +// Warning: (181-184): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_function_050.sol b/test/libsolidity/syntaxTests/types/empty_tuple_function_050.sol new file mode 100644 index 00000000..c4b9e03f --- /dev/null +++ b/test/libsolidity/syntaxTests/types/empty_tuple_function_050.sol @@ -0,0 +1,11 @@ +pragma experimental "v0.5.0"; +contract C { + function f() private pure {} + function a() public pure { + bool x = true; + bool y = true; + (x) ? (f(), y = false) : (f(), y = false); + } +} +// ---- +// TypeError: (168-171): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_lvalue.sol b/test/libsolidity/syntaxTests/types/empty_tuple_lvalue.sol new file mode 100644 index 00000000..cba30c1b --- /dev/null +++ b/test/libsolidity/syntaxTests/types/empty_tuple_lvalue.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.4.3; +contract C { + function f() private pure {} + function a() public { + uint x; + uint y; + (x, y) = (f(), f()); + } +} +// ---- +// Warning: (146-149): Tuple component cannot be empty. +// Warning: (151-154): Tuple component cannot be empty. +// TypeError: (145-155): Type tuple(tuple(),tuple()) is not implicitly convertible to expected type tuple(uint256,uint256). diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_lvalue_050.sol b/test/libsolidity/syntaxTests/types/empty_tuple_lvalue_050.sol new file mode 100644 index 00000000..b0691778 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/empty_tuple_lvalue_050.sol @@ -0,0 +1,11 @@ +pragma experimental "v0.5.0"; +contract C { + function f() private pure {} + function a() public { + uint x; + uint y; + (x, y) = (f(), f()); + } +} +// ---- +// TypeError: (152-155): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_lvalue_array.sol b/test/libsolidity/syntaxTests/types/empty_tuple_lvalue_array.sol new file mode 100644 index 00000000..f8b2ae7e --- /dev/null +++ b/test/libsolidity/syntaxTests/types/empty_tuple_lvalue_array.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.4.3; +contract C { + function f() private pure {} + function a() public { + uint x; + uint y; + (x, y) = [f(), f()]; + } +} +// ---- +// TypeError: (146-149): Array component cannot be empty. diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index febb0c26..11714017 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -1,5 +1,5 @@ add_executable(solfuzzer fuzzer.cpp) -target_link_libraries(solfuzzer PRIVATE libsolc evmasm ${Boost_PROGRAM_OPTIONS_LIBRARIES}) +target_link_libraries(solfuzzer PRIVATE libsolc evmasm ${Boost_PROGRAM_OPTIONS_LIBRARIES} ${Boost_SYSTEM_LIBRARIES}) add_executable(isoltest isoltest.cpp ../Options.cpp ../libsolidity/SyntaxTest.cpp ../libsolidity/AnalysisFramework.cpp) target_link_libraries(isoltest PRIVATE libsolc solidity evmasm ${Boost_PROGRAM_OPTIONS_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) |
