diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 14 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 85 | ||||
-rw-r--r-- | test/libsolidity/SolidityOptimizer.cpp | 62 | ||||
-rw-r--r-- | test/libsolidity/SolidityScanner.cpp | 18 |
4 files changed, 171 insertions, 8 deletions
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 130b0d3a..baed3f1e 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7260,6 +7260,20 @@ BOOST_AUTO_TEST_CASE(inline_array_return) BOOST_CHECK(callContractFunction("f()") == encodeArgs(1, 2, 3, 4, 5)); } +BOOST_AUTO_TEST_CASE(inline_array_singleton) +{ + // This caused a failure since the type was not converted to its mobile type. + char const* sourceCode = R"( + contract C { + function f() returns (uint) { + return [4][0]; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(4))); +} + BOOST_AUTO_TEST_CASE(inline_long_string_return) { char const* sourceCode = R"( diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 437f2adc..dda7105c 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -20,19 +20,23 @@ * Unit tests for the name and type resolution of the solidity parser. */ -#include <string> +#include <test/libsolidity/ErrorCheck.h> + +#include <test/TestHelper.h> -#include <libdevcore/SHA3.h> #include <libsolidity/parsing/Scanner.h> #include <libsolidity/parsing/Parser.h> #include <libsolidity/analysis/NameAndTypeResolver.h> #include <libsolidity/analysis/StaticAnalyzer.h> +#include <libsolidity/analysis/PostTypeChecker.h> #include <libsolidity/analysis/SyntaxChecker.h> #include <libsolidity/interface/Exceptions.h> #include <libsolidity/analysis/GlobalContext.h> #include <libsolidity/analysis/TypeChecker.h> -#include "../TestHelper.h" -#include "ErrorCheck.h" + +#include <libdevcore/SHA3.h> + +#include <string> using namespace std; @@ -93,10 +97,11 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false, BOOST_CHECK(success || !errors.empty()); } if (success) - { - StaticAnalyzer staticAnalyzer(errors); - staticAnalyzer.analyze(*sourceUnit); - } + if (!PostTypeChecker(errors).check(*sourceUnit)) + success = false; + if (success) + if (!StaticAnalyzer(errors).analyze(*sourceUnit)) + success = false; if (errors.size() > 1 && !_allowMultipleErrors) BOOST_FAIL("Multiple errors found"); for (auto const& currentError: errors) @@ -2501,6 +2506,30 @@ BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable) CHECK_ERROR(sourceCode, TypeError, ""); } +BOOST_AUTO_TEST_CASE(uninitialized_mapping_variable) +{ + char const* sourceCode = R"( + contract C { + function f() { + mapping(uint => uint) x; + } + } + )"; + CHECK_ERROR(sourceCode, TypeError, "Uninitialized mapping. Mappings cannot be created dynamically, you have to assign them from a state variable"); +} + +BOOST_AUTO_TEST_CASE(uninitialized_mapping_array_variable) +{ + char const* sourceCode = R"( + contract C { + function f() { + mapping(uint => uint)[] x; + } + } + )"; + CHECK_WARNING(sourceCode, "Uninitialized storage pointer"); +} + BOOST_AUTO_TEST_CASE(no_delete_on_storage_pointers) { char const* sourceCode = R"( @@ -2963,6 +2992,18 @@ BOOST_AUTO_TEST_CASE(tuple_assignment_from_void_function) CHECK_ERROR(text, TypeError, "Cannot declare variable with void (empty tuple) type."); } +BOOST_AUTO_TEST_CASE(tuple_compound_assignment) +{ + char const* text = R"( + contract C { + function f() returns (uint a, uint b) { + (a, b) += (1, 1); + } + } + )"; + CHECK_ERROR(text, TypeError, "Compound assignment is not allowed for tuple types."); +} + BOOST_AUTO_TEST_CASE(member_access_parser_ambiguity) { char const* text = R"( @@ -5174,6 +5215,34 @@ BOOST_AUTO_TEST_CASE(address_methods) CHECK_SUCCESS(text); } +BOOST_AUTO_TEST_CASE(cyclic_dependency_for_constants) +{ + char const* text = R"( + contract C { + uint constant a = a; + } + )"; + CHECK_ERROR(text, TypeError, "cyclic dependency via a"); + text = R"( + contract C { + uint constant a = b * c; + uint constant b = 7; + uint constant c = b + uint(sha3(d)); + uint constant d = 2 + a; + } + )"; + CHECK_ERROR_ALLOW_MULTI(text, TypeError, "a has a cyclic dependency via c"); + text = R"( + contract C { + uint constant a = b * c; + uint constant b = 7; + uint constant c = 4 + uint(sha3(d)); + uint constant d = 2 + b; + } + )"; + CHECK_SUCCESS(text); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 2e2e0c6c..bcf6cd49 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -31,6 +31,7 @@ #include <boost/test/unit_test.hpp> #include <boost/lexical_cast.hpp> +#include <chrono> #include <string> #include <tuple> #include <memory> @@ -1234,6 +1235,67 @@ BOOST_AUTO_TEST_CASE(computing_constants) ) == optimizedBytecode.cend()); } + +BOOST_AUTO_TEST_CASE(constant_optimization_early_exit) +{ + // This tests that the constant optimizer does not try to find the best representation + // indefinitely but instead stops after some number of iterations. + char const* sourceCode = R"( + pragma solidity ^0.4.0; + + contract HexEncoding { + function hexEncodeTest(address addr) returns (bytes32 ret) { + uint x = uint(addr) / 2**32; + + // Nibble interleave + x = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff; + x = (x | (x * 2**64)) & 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff; + x = (x | (x * 2**32)) & 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff; + x = (x | (x * 2**16)) & 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff; + x = (x | (x * 2** 8)) & 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff; + x = (x | (x * 2** 4)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f; + + // Hex encode + uint h = (x & 0x0808080808080808080808080808080808080808080808080808080808080808) / 8; + uint i = (x & 0x0404040404040404040404040404040404040404040404040404040404040404) / 4; + uint j = (x & 0x0202020202020202020202020202020202020202020202020202020202020202) / 2; + x = x + (h & (i | j)) * 0x27 + 0x3030303030303030303030303030303030303030303030303030303030303030; + + // Store and load next batch + assembly { + mstore(0, x) + } + x = uint(addr) * 2**96; + + // Nibble interleave + x = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff; + x = (x | (x * 2**64)) & 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff; + x = (x | (x * 2**32)) & 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff; + x = (x | (x * 2**16)) & 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff; + x = (x | (x * 2** 8)) & 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff; + x = (x | (x * 2** 4)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f; + + // Hex encode + h = (x & 0x0808080808080808080808080808080808080808080808080808080808080808) / 8; + i = (x & 0x0404040404040404040404040404040404040404040404040404040404040404) / 4; + j = (x & 0x0202020202020202020202020202020202020202020202020202020202020202) / 2; + x = x + (h & (i | j)) * 0x27 + 0x3030303030303030303030303030303030303030303030303030303030303030; + + // Store and hash + assembly { + mstore(32, x) + ret := sha3(0, 40) + } + } + } + )"; + auto start = std::chrono::steady_clock::now(); + compileBothVersions(sourceCode); + double duration = std::chrono::duration<double>(std::chrono::steady_clock::now() - start).count(); + BOOST_CHECK_MESSAGE(duration < 20, "Compilation of constants took longer than 20 seconds."); + compareVersions("hexEncodeTest(address)", u256(0x123456789)); +} + BOOST_AUTO_TEST_CASE(inconsistency) { // This is a test of a bug in the optimizer. diff --git a/test/libsolidity/SolidityScanner.cpp b/test/libsolidity/SolidityScanner.cpp index eb2f042c..3a5c6f24 100644 --- a/test/libsolidity/SolidityScanner.cpp +++ b/test/libsolidity/SolidityScanner.cpp @@ -97,6 +97,24 @@ BOOST_AUTO_TEST_CASE(hex_numbers) BOOST_CHECK_EQUAL(scanner.next(), Token::EOS); } +BOOST_AUTO_TEST_CASE(octal_numbers) +{ + Scanner scanner(CharStream("07")); + BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal); + scanner.reset(CharStream("007"), ""); + BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal); + scanner.reset(CharStream("-07"), ""); + BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Sub); + BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal); + scanner.reset(CharStream("-.07"), ""); + BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Sub); + BOOST_CHECK_EQUAL(scanner.next(), Token::Number); + scanner.reset(CharStream("0"), ""); + BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number); + scanner.reset(CharStream("0.1"), ""); + BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number); +} + BOOST_AUTO_TEST_CASE(negative_numbers) { Scanner scanner(CharStream("var x = -.2 + -0x78 + -7.3 + 8.9;")); |