diff options
Diffstat (limited to 'test/libsolidity')
21 files changed, 258 insertions, 234 deletions
diff --git a/test/libsolidity/SolidityCompiler.cpp b/test/libsolidity/SolidityCompiler.cpp new file mode 100644 index 00000000..e87ab603 --- /dev/null +++ b/test/libsolidity/SolidityCompiler.cpp @@ -0,0 +1,60 @@ +/* + 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/>. + */ +/** + * Unit tests for the compiler itself. + */ + +#include <test/libsolidity/AnalysisFramework.h> + +#include <test/Options.h> + +using namespace std; + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +BOOST_FIXTURE_TEST_SUITE(Compiler, AnalysisFramework) + +BOOST_AUTO_TEST_CASE(does_not_include_creation_time_only_internal_functions) +{ + char const* sourceCode = R"( + contract C { + uint x; + function C() { f(); } + function f() internal { for (uint i = 0; i < 10; ++i) x += 3 + i; } + } + )"; + BOOST_REQUIRE(success(sourceCode)); + m_compiler.setOptimiserSettings(dev::test::Options::get().optimize); + BOOST_REQUIRE_MESSAGE(m_compiler.compile(), "Compiling contract failed"); + bytes const& creationBytecode = m_compiler.object("C").bytecode; + bytes const& runtimeBytecode = m_compiler.runtimeObject("C").bytecode; + BOOST_CHECK(creationBytecode.size() >= 120); + BOOST_CHECK(creationBytecode.size() <= 150); + BOOST_CHECK(runtimeBytecode.size() >= 50); + BOOST_CHECK(runtimeBytecode.size() <= 70); +} + +BOOST_AUTO_TEST_SUITE_END() + +} +} +} diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 44dc40f7..a866e46c 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1805,6 +1805,18 @@ BOOST_AUTO_TEST_CASE(uncalled_blockhash) BOOST_CHECK(result[0] != 0 || result[1] != 0 || result[2] != 0); } +BOOST_AUTO_TEST_CASE(blockhash_shadow_resolution) +{ + char const* code = R"( + contract C { + function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; } + function f() public returns(bytes32) { return blockhash(3); } + } + )"; + compileAndRun(code, 0, "C"); + ABI_CHECK(callContractFunction("f()"), encodeArgs(0)); +} + BOOST_AUTO_TEST_CASE(log0) { char const* sourceCode = R"( diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index c8adfc6e..90d8265c 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -503,12 +503,15 @@ BOOST_AUTO_TEST_CASE(blockhash) char const* sourceCode = R"( contract test { function f() { - block.blockhash(3); + blockhash(3); } } )"; - bytes code = compileFirstExpression(sourceCode, {}, {}, - {make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::Block))}); + + auto blockhashFun = make_shared<FunctionType>(strings{"uint256"}, strings{"bytes32"}, + FunctionType::Kind::BlockHash, false, StateMutability::View); + + bytes code = compileFirstExpression(sourceCode, {}, {}, {make_shared<MagicVariableDeclaration>("blockhash", blockhashFun)}); bytes expectation({byte(Instruction::PUSH1), 0x03, byte(Instruction::BLOCKHASH)}); diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index e30ea8a4..c5abac03 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -43,229 +43,6 @@ namespace test BOOST_FIXTURE_TEST_SUITE(SolidityNameAndTypeResolution, AnalysisFramework) - -BOOST_AUTO_TEST_CASE(double_function_declaration) -{ - char const* text = R"( - contract test { - function fun() public { } - function fun() public { } - } - )"; - CHECK_ERROR(text, DeclarationError, "Function with same name and arguments defined twice."); -} - -BOOST_AUTO_TEST_CASE(double_variable_declaration_disjoint_scope) -{ - string text = R"( - contract test { - function f() pure public { - { uint x; } - { uint x; } - } - } - )"; - CHECK_ERROR(text, DeclarationError, "Identifier already declared"); -} - -BOOST_AUTO_TEST_CASE(double_variable_declaration_disjoint_scope_050) -{ - string text = R"( - pragma experimental "v0.5.0"; - contract test { - function f() pure public { - { uint x; } - { uint x; } - } - } - )"; - CHECK_WARNING_ALLOW_MULTI(text, (vector<string>{ - "Unused local variable", - "Unused local variable" - })); -} - -BOOST_AUTO_TEST_CASE(double_variable_declaration_disjoint_scope_activation) -{ - string text = R"( - contract test { - function f() pure public { - { uint x; } - uint x; - } - } - )"; - CHECK_ERROR(text, DeclarationError, "Identifier already declared"); -} - -BOOST_AUTO_TEST_CASE(double_variable_declaration_disjoint_scope_activation_050) -{ - string text = R"( - pragma experimental "v0.5.0"; - contract test { - function f() pure public { - { uint x; } - uint x; - } - } - )"; - CHECK_WARNING_ALLOW_MULTI(text, (vector<string>{ - "Unused local variable", - "Unused local variable" - })); -} -BOOST_AUTO_TEST_CASE(scoping_old) -{ - char const* text = R"( - contract test { - function f() pure public { - x = 4; - uint256 x = 2; - } - } - )"; - CHECK_SUCCESS_NO_WARNINGS(text); -} - -BOOST_AUTO_TEST_CASE(scoping) -{ - char const* text = R"( - pragma experimental "v0.5.0"; - contract test { - function f() public { - { - uint256 x; - } - x = 2; - } - } - )"; - CHECK_ERROR(text, DeclarationError, "Undeclared identifier"); -} - -BOOST_AUTO_TEST_CASE(scoping_activation_old) -{ - char const* text = R"( - contract test { - function f() pure public { - x = 3; - uint x; - } - } - )"; - CHECK_SUCCESS_NO_WARNINGS(text); -} - -BOOST_AUTO_TEST_CASE(scoping_activation) -{ - char const* text = R"( - pragma experimental "v0.5.0"; - contract test { - function f() pure public { - x = 3; - uint x; - } - } - )"; - CHECK_ERROR(text, DeclarationError, "Undeclared identifier"); -} - -BOOST_AUTO_TEST_CASE(scoping_self_use) -{ - char const* text = R"( - contract test { - function f() pure public { - uint a = a; - } - } - )"; - CHECK_SUCCESS_NO_WARNINGS(text); -} - -BOOST_AUTO_TEST_CASE(scoping_self_use_050) -{ - char const* text = R"( - pragma experimental "v0.5.0"; - contract test { - function f() pure public { - uint a = a; - } - } - )"; - CHECK_ERROR(text, DeclarationError, "Undeclared identifier"); -} - -BOOST_AUTO_TEST_CASE(scoping_for) -{ - char const* text = R"( - pragma experimental "v0.5.0"; - contract test { - function f() pure public { - for (uint x = 0; x < 10; x ++){ - x = 2; - } - } - } - )"; - CHECK_SUCCESS_NO_WARNINGS(text); -} - -BOOST_AUTO_TEST_CASE(scoping_for2) -{ - char const* text = R"( - pragma experimental "v0.5.0"; - contract test { - function f() pure public { - for (uint x = 0; x < 10; x ++) - x = 2; - } - } - )"; - CHECK_SUCCESS_NO_WARNINGS(text); -} - -BOOST_AUTO_TEST_CASE(scoping_for3) -{ - char const* text = R"( - pragma experimental "v0.5.0"; - contract test { - function f() pure public { - for (uint x = 0; x < 10; x ++){ - x = 2; - } - x = 4; - } - } - )"; - CHECK_ERROR(text, DeclarationError, "Undeclared identifier"); -} - -BOOST_AUTO_TEST_CASE(scoping_for_decl_in_body) -{ - char const* text = R"( - pragma experimental "v0.5.0"; - contract test { - function f() pure public { - for (;; y++){ - uint y = 3; - } - } - } - )"; - CHECK_ERROR(text, DeclarationError, "Undeclared identifier"); -} - -BOOST_AUTO_TEST_CASE(name_shadowing) -{ - char const* text = R"( - contract test { - uint256 variable; - function f() public { uint32 variable; variable = 2; } - } - )"; - CHECK_SUCCESS(text); -} - BOOST_AUTO_TEST_CASE(name_references) { char const* text = R"( @@ -8569,6 +8346,33 @@ BOOST_AUTO_TEST_CASE(require_visibility_specifiers) CHECK_ERROR(text, SyntaxError, "No visibility specified."); } +BOOST_AUTO_TEST_CASE(blockhash) +{ + char const* code = R"( + contract C { + function f() public view returns (bytes32) { + return block.blockhash(3); + } + } + )"; + CHECK_WARNING(code, "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""); + + code = R"( + contract C { + function f() public view returns (bytes32) { return blockhash(3); } + } + )"; + CHECK_SUCCESS_NO_WARNINGS(code); + + code = R"( + pragma experimental "v0.5.0"; + contract C { + function f() public returns (bytes32) { return block.blockhash(3); } + } + )"; + CHECK_ERROR(code, TypeError, "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp index a6ce6d91..cd0a0b01 100644 --- a/test/libsolidity/ViewPureChecker.cpp +++ b/test/libsolidity/ViewPureChecker.cpp @@ -25,6 +25,7 @@ #include <boost/test/unit_test.hpp> #include <string> +#include <tuple> using namespace std; @@ -111,6 +112,7 @@ BOOST_AUTO_TEST_CASE(environment_access) "block.difficulty", "block.number", "block.gaslimit", + "blockhash(7)", "gasleft()", "msg.gas", "msg.value", @@ -120,11 +122,12 @@ BOOST_AUTO_TEST_CASE(environment_access) "this", "address(1).balance" }; + // ``block.blockhash`` and ``blockhash`` are tested seperately below because their usage will + // produce warnings that can't be handled in a generic way. vector<string> pure{ "msg.data", "msg.data[0]", "msg.sig", - "block.blockhash", // Not evaluating the function "msg", "block", "tx" @@ -132,20 +135,32 @@ BOOST_AUTO_TEST_CASE(environment_access) for (string const& x: view) { CHECK_ERROR( - "contract C { function f() pure public { var x = " + x + "; x; } }", + "contract C { function f() pure public { " + x + "; } }", TypeError, "Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires \"view\"" ); } for (string const& x: pure) { - CHECK_WARNING_ALLOW_MULTI( - "contract C { function f() view public { var x = " + x + "; x; } }", - (std::vector<std::string>{ - "Function state mutability can be restricted to pure", - "Use of the \"var\" keyword is deprecated." - })); + CHECK_WARNING( + "contract C { function f() view public { " + x + "; } }", + "Function state mutability can be restricted to pure" + ); } + + CHECK_WARNING_ALLOW_MULTI( + "contract C { function f() view public { blockhash; } }", + (std::vector<std::string>{ + "Function state mutability can be restricted to pure", + "Statement has no effect." + })); + + CHECK_WARNING_ALLOW_MULTI( + "contract C { function f() view public { block.blockhash; } }", + (std::vector<std::string>{ + "Function state mutability can be restricted to pure", + "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"" + })); } BOOST_AUTO_TEST_CASE(view_error_for_050) diff --git a/test/libsolidity/syntaxTests/scoping/double_function_declaration.sol b/test/libsolidity/syntaxTests/scoping/double_function_declaration.sol new file mode 100644 index 00000000..2841fd38 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/double_function_declaration.sol @@ -0,0 +1,6 @@ +contract test { + function fun() public { } + function fun() public { } +} +// ---- +// DeclarationError: Function with same name and arguments defined twice. diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol new file mode 100644 index 00000000..ea61d0f3 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol @@ -0,0 +1,8 @@ +contract test { + function f() pure public { + { uint x; } + { uint x; } + } +} +// ---- +// DeclarationError: Identifier already declared. diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol new file mode 100644 index 00000000..22195963 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol @@ -0,0 +1,10 @@ +pragma experimental "v0.5.0"; +contract test { + function f() pure public { + { uint x; } + { uint x; } + } +} +// ---- +// Warning: Unused local variable. +// Warning: Unused local variable. diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol new file mode 100644 index 00000000..6af89c93 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol @@ -0,0 +1,8 @@ +contract test { + function f() pure public { + { uint x; } + uint x; + } +} +// ---- +// DeclarationError: Identifier already declared. diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol new file mode 100644 index 00000000..73cddfed --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol @@ -0,0 +1,10 @@ +pragma experimental "v0.5.0"; +contract test { + function f() pure public { + { uint x; } + uint x; + } +} +// ---- +// Warning: Unused local variable. +// Warning: Unused local variable. diff --git a/test/libsolidity/syntaxTests/scoping/name_shadowing.sol b/test/libsolidity/syntaxTests/scoping/name_shadowing.sol new file mode 100644 index 00000000..d16877f9 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/name_shadowing.sol @@ -0,0 +1,7 @@ +contract test { + uint256 variable; + function f() pure public { uint32 variable; variable = 2; } +} +// ---- +// Warning: This declaration shadows an existing declaration. + diff --git a/test/libsolidity/syntaxTests/scoping/scoping.sol b/test/libsolidity/syntaxTests/scoping/scoping.sol new file mode 100644 index 00000000..f47a3e99 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/scoping.sol @@ -0,0 +1,11 @@ +pragma experimental "v0.5.0"; +contract test { + function f() public { + { + uint256 x; + } + x = 2; + } +} +// ---- +// DeclarationError: Undeclared identifier. diff --git a/test/libsolidity/syntaxTests/scoping/scoping_activation.sol b/test/libsolidity/syntaxTests/scoping/scoping_activation.sol new file mode 100644 index 00000000..0ed74a00 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/scoping_activation.sol @@ -0,0 +1,9 @@ +pragma experimental "v0.5.0"; +contract test { + function f() pure public { + x = 3; + uint x; + } +} +// ---- +// DeclarationError: Undeclared identifier. Did you mean "x"? diff --git a/test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol b/test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol new file mode 100644 index 00000000..d893a889 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol @@ -0,0 +1,6 @@ +contract test { + function f() pure public { + x = 3; + uint x; + } +} diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for.sol b/test/libsolidity/syntaxTests/scoping/scoping_for.sol new file mode 100644 index 00000000..6e5b7095 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/scoping_for.sol @@ -0,0 +1,8 @@ +pragma experimental "v0.5.0"; +contract test { + function f() pure public { + for (uint x = 0; x < 10; x ++){ + x = 2; + } + } +} diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for2.sol b/test/libsolidity/syntaxTests/scoping/scoping_for2.sol new file mode 100644 index 00000000..eb74b8ab --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/scoping_for2.sol @@ -0,0 +1,7 @@ +pragma experimental "v0.5.0"; +contract test { + function f() pure public { + for (uint x = 0; x < 10; x ++) + x = 2; + } +} diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for3.sol b/test/libsolidity/syntaxTests/scoping/scoping_for3.sol new file mode 100644 index 00000000..9bc7d569 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/scoping_for3.sol @@ -0,0 +1,11 @@ +pragma experimental "v0.5.0"; +contract test { + function f() pure public { + for (uint x = 0; x < 10; x ++){ + x = 2; + } + x = 4; + } +} +// ---- +// DeclarationError: Undeclared identifier. diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol b/test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol new file mode 100644 index 00000000..07503983 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol @@ -0,0 +1,10 @@ +pragma experimental "v0.5.0"; +contract test { + function f() pure public { + for (;; y++){ + uint y = 3; + } + } +} +// ---- +// DeclarationError: Undeclared identifier. diff --git a/test/libsolidity/syntaxTests/scoping/scoping_old.sol b/test/libsolidity/syntaxTests/scoping/scoping_old.sol new file mode 100644 index 00000000..83f6b60b --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/scoping_old.sol @@ -0,0 +1,6 @@ +contract test { + function f() pure public { + x = 4; + uint256 x = 2; + } +} diff --git a/test/libsolidity/syntaxTests/scoping/scoping_self_use.sol b/test/libsolidity/syntaxTests/scoping/scoping_self_use.sol new file mode 100644 index 00000000..9e2c0171 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/scoping_self_use.sol @@ -0,0 +1,5 @@ +contract test { + function f() pure public { + uint a = a; + } +} diff --git a/test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol b/test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol new file mode 100644 index 00000000..e942020e --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol @@ -0,0 +1,8 @@ +pragma experimental "v0.5.0"; +contract test { + function f() pure public { + uint a = a; + } +} +// ---- +// DeclarationError: Undeclared identifier. Did you mean "a"? |