diff options
Diffstat (limited to 'test/libsolidity')
-rw-r--r-- | test/libsolidity/GasMeter.cpp | 2 | ||||
-rw-r--r-- | test/libsolidity/InlineAssembly.cpp | 21 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 348 | ||||
-rw-r--r-- | test/libsolidity/SolidityExecutionFramework.h | 12 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 227 | ||||
-rw-r--r-- | test/libsolidity/SolidityOptimizer.cpp | 4 |
6 files changed, 583 insertions, 31 deletions
diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp index 1f216680..fc103393 100644 --- a/test/libsolidity/GasMeter.cpp +++ b/test/libsolidity/GasMeter.cpp @@ -82,7 +82,7 @@ public: { u256 gasUsed = 0; GasMeter::GasConsumption gas; - FixedHash<4> hash(dev::sha3(_sig)); + FixedHash<4> hash(dev::keccak256(_sig)); for (bytes const& arguments: _argumentVariants) { sendMessage(hash.asBytes() + arguments, false, 0); diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 8d1a1d6c..6c04367f 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -51,7 +51,7 @@ bool successParse(std::string const& _source, bool _assemble = false) if (_assemble) { stack.assemble(); - if (!stack.errors().empty()) + if (!stack.errors().empty() && !Error::containsOnlyWarnings(stack.errors())) return false; } } @@ -87,9 +87,14 @@ BOOST_AUTO_TEST_CASE(simple_instructions) BOOST_CHECK(successParse("{ dup1 dup1 mul dup1 sub }")); } +BOOST_AUTO_TEST_CASE(suicide_selfdestruct) +{ + BOOST_CHECK(successParse("{ suicide selfdestruct }")); +} + BOOST_AUTO_TEST_CASE(keywords) { - BOOST_CHECK(successParse("{ byte return }")); + BOOST_CHECK(successParse("{ byte return address }")); } BOOST_AUTO_TEST_CASE(constants) @@ -152,6 +157,18 @@ BOOST_AUTO_TEST_CASE(oversize_string_literals) BOOST_CHECK(!successAssemble("{ let x := \"123456789012345678901234567890123\" }")); } +BOOST_AUTO_TEST_CASE(assignment_after_tag) +{ + BOOST_CHECK(successParse("{ let x := 1 { tag: =: x } }")); +} + +BOOST_AUTO_TEST_CASE(magic_variables) +{ + BOOST_CHECK(!successAssemble("{ this }")); + BOOST_CHECK(!successAssemble("{ ecrecover }")); + BOOST_CHECK(successAssemble("{ let ecrecover := 1 ecrecover }")); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 23bd2abc..8ef9a45b 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1260,7 +1260,7 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors) compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("data()") == encodeArgs(8)); BOOST_CHECK(callContractFunction("name()") == encodeArgs("Celina")); - BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::sha3(bytes(1, 0x7b)))); + BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::keccak256(bytes(1, 0x7b)))); BOOST_CHECK(callContractFunction("an_address()") == encodeArgs(toBigEndian(u160(0x1337)))); BOOST_CHECK(callContractFunction("super_secret_data()") == bytes()); } @@ -1342,7 +1342,7 @@ BOOST_AUTO_TEST_CASE(msg_sig) } )"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("foo(uint256)") == encodeArgs(asString(FixedHash<4>(dev::sha3("foo(uint256)")).asBytes()))); + BOOST_CHECK(callContractFunction("foo(uint256)") == encodeArgs(asString(FixedHash<4>(dev::keccak256("foo(uint256)")).asBytes()))); } BOOST_AUTO_TEST_CASE(msg_sig_after_internal_call_is_same) @@ -1358,7 +1358,7 @@ BOOST_AUTO_TEST_CASE(msg_sig_after_internal_call_is_same) } )"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("foo(uint256)") == encodeArgs(asString(FixedHash<4>(dev::sha3("foo(uint256)")).asBytes()))); + BOOST_CHECK(callContractFunction("foo(uint256)") == encodeArgs(asString(FixedHash<4>(dev::keccak256("foo(uint256)")).asBytes()))); } BOOST_AUTO_TEST_CASE(now) @@ -1686,7 +1686,7 @@ BOOST_AUTO_TEST_CASE(sha3) compileAndRun(sourceCode); auto f = [&](u256 const& _x) -> u256 { - return dev::sha3(toBigEndian(_x)); + return dev::keccak256(toBigEndian(_x)); }; testSolidityAgainstCpp("a(bytes32)", f, u256(4)); testSolidityAgainstCpp("a(bytes32)", f, u256(5)); @@ -2513,6 +2513,15 @@ BOOST_AUTO_TEST_CASE(super_in_constructor) BOOST_CHECK(callContractFunction("f()") == encodeArgs(1 | 2 | 4 | 8)); } +BOOST_AUTO_TEST_CASE(super_alone) +{ + char const* sourceCode = R"( + contract A { function f() { super; } } + )"; + compileAndRun(sourceCode, 0, "A"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs()); +} + BOOST_AUTO_TEST_CASE(fallback_function) { char const* sourceCode = R"( @@ -2582,7 +2591,7 @@ BOOST_AUTO_TEST_CASE(event) BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(value))); BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 3); - BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,bytes32,uint256)"))); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,bytes32,uint256)"))); BOOST_CHECK_EQUAL(m_logs[0].topics[1], h256(m_sender, h256::AlignRight)); BOOST_CHECK_EQUAL(m_logs[0].topics[2], h256(id)); } @@ -2604,7 +2613,7 @@ BOOST_AUTO_TEST_CASE(event_no_arguments) BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); BOOST_CHECK(m_logs[0].data.empty()); BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); - BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit()"))); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit()"))); } BOOST_AUTO_TEST_CASE(event_anonymous) @@ -2664,7 +2673,7 @@ BOOST_AUTO_TEST_CASE(event_lots_of_data) BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); BOOST_CHECK(m_logs[0].data == encodeArgs((u160)m_sender, id, value, true)); BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); - BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,bytes32,uint256,bool)"))); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,bytes32,uint256,bool)"))); } BOOST_AUTO_TEST_CASE(event_really_lots_of_data) @@ -2681,9 +2690,9 @@ BOOST_AUTO_TEST_CASE(event_really_lots_of_data) callContractFunction("deposit()"); BOOST_REQUIRE_EQUAL(m_logs.size(), 1); BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); - BOOST_CHECK(m_logs[0].data == encodeArgs(10, 0x60, 15, 4) + FixedHash<4>(dev::sha3("deposit()")).asBytes()); + BOOST_CHECK(m_logs[0].data == encodeArgs(10, 0x60, 15, 4) + FixedHash<4>(dev::keccak256("deposit()")).asBytes()); BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); - BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(uint256,bytes,uint256)"))); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)"))); } BOOST_AUTO_TEST_CASE(event_really_lots_of_data_from_storage) @@ -2707,7 +2716,7 @@ BOOST_AUTO_TEST_CASE(event_really_lots_of_data_from_storage) BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); BOOST_CHECK(m_logs[0].data == encodeArgs(10, 0x60, 15, 3, string("ABC"))); BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); - BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(uint256,bytes,uint256)"))); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)"))); } BOOST_AUTO_TEST_CASE(event_indexed_string) @@ -2738,11 +2747,11 @@ BOOST_AUTO_TEST_CASE(event_indexed_string) dynx[i] = i; BOOST_CHECK(m_logs[0].data == bytes()); BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 3); - BOOST_CHECK_EQUAL(m_logs[0].topics[1], dev::sha3(dynx)); - BOOST_CHECK_EQUAL(m_logs[0].topics[2], dev::sha3( + BOOST_CHECK_EQUAL(m_logs[0].topics[1], dev::keccak256(dynx)); + BOOST_CHECK_EQUAL(m_logs[0].topics[2], dev::keccak256( encodeArgs(u256(4), u256(5), u256(6), u256(7)) )); - BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("E(string,uint256[4])"))); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(string,uint256[4])"))); } BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one) @@ -2784,7 +2793,7 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments) compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("foo(uint256,uint256,uint256)", 10, 12, 13) == encodeArgs( - dev::sha3( + dev::keccak256( toBigEndian(u256(10)) + toBigEndian(u256(12)) + toBigEndian(u256(13))))); @@ -2802,7 +2811,7 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals) compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("foo(uint256,uint16)", 10, 12) == encodeArgs( - dev::sha3( + dev::keccak256( toBigEndian(u256(10)) + bytes{0x0, 0xc} + bytes(1, 0x91)))); @@ -2823,10 +2832,10 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) })"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("foo()") == encodeArgs(dev::sha3("foo"))); + BOOST_CHECK(callContractFunction("foo()") == encodeArgs(dev::keccak256("foo"))); BOOST_CHECK(callContractFunction("bar(uint256,uint16)", 10, 12) == encodeArgs( - dev::sha3( + dev::keccak256( toBigEndian(u256(10)) + bytes{0x0, 0xc} + bytes(1, 0x91) + @@ -2868,7 +2877,27 @@ BOOST_AUTO_TEST_CASE(iterated_sha3_with_bytes) )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("foo()") == encodeArgs( - u256(dev::sha3(bytes{'b'} + dev::sha3("xyz").asBytes() + bytes{'a'})) + u256(dev::keccak256(bytes{'b'} + dev::keccak256("xyz").asBytes() + bytes{'a'})) + )); +} + +BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments) +{ + char const* sourceCode = R"( + contract c { + function foo(uint a, uint b, uint c) returns (bytes32 d) + { + d = keccak256(a, b, c); + } + })"; + compileAndRun(sourceCode); + + BOOST_CHECK(callContractFunction("foo(uint256,uint256,uint256)", 10, 12, 13) == encodeArgs( + dev::keccak256( + toBigEndian(u256(10)) + + toBigEndian(u256(12)) + + toBigEndian(u256(13)) + ) )); } @@ -3013,9 +3042,9 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory) } )"; compileAndRun(sourceCode); - bytes calldata1 = FixedHash<4>(dev::sha3("f()")).asBytes() + bytes(61, 0x22) + bytes(12, 0x12); + bytes calldata1 = FixedHash<4>(dev::keccak256("f()")).asBytes() + bytes(61, 0x22) + bytes(12, 0x12); sendMessage(calldata1, false); - BOOST_CHECK(m_output == encodeArgs(dev::sha3(bytes{'a', 'b', 'c'} + calldata1))); + BOOST_CHECK(m_output == encodeArgs(dev::keccak256(bytes{'a', 'b', 'c'} + calldata1))); } BOOST_AUTO_TEST_CASE(call_forward_bytes) @@ -3285,6 +3314,57 @@ BOOST_AUTO_TEST_CASE(using_enums) BOOST_CHECK(callContractFunction("getChoice()") == encodeArgs(2)); } +BOOST_AUTO_TEST_CASE(using_contract_enums_with_explicit_contract_name) +{ + char const* sourceCode = R"( + contract test { + enum Choice { A, B, C } + function answer () returns (test.Choice _ret) + { + _ret = test.Choice.B; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("answer()") == encodeArgs(1)); +} + +BOOST_AUTO_TEST_CASE(using_inherited_enum) +{ + char const* sourceCode = R"( + contract base { + enum Choice { A, B, C } + } + + contract test is base { + function answer () returns (Choice _ret) + { + _ret = Choice.B; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("answer()") == encodeArgs(1)); +} + +BOOST_AUTO_TEST_CASE(using_inherited_enum_excplicitly) +{ + char const* sourceCode = R"( + contract base { + enum Choice { A, B, C } + } + + contract test is base { + function answer () returns (base.Choice _ret) + { + _ret = base.Choice.B; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("answer()") == encodeArgs(1)); +} + BOOST_AUTO_TEST_CASE(constructing_enums_from_ints) { char const* sourceCode = R"( @@ -3389,8 +3469,8 @@ BOOST_AUTO_TEST_CASE(bytes_in_arguments) )"; compileAndRun(sourceCode); - string innercalldata1 = asString(FixedHash<4>(dev::sha3("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9)); - string innercalldata2 = asString(FixedHash<4>(dev::sha3("g(uint256)")).asBytes() + encodeArgs(3)); + string innercalldata1 = asString(FixedHash<4>(dev::keccak256("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9)); + string innercalldata2 = asString(FixedHash<4>(dev::keccak256("g(uint256)")).asBytes() + encodeArgs(3)); bytes calldata = encodeArgs( 12, 32 * 4, u256(32 * 4 + 32 + (innercalldata1.length() + 31) / 32 * 32), 13, u256(innercalldata1.length()), innercalldata1, @@ -4668,7 +4748,7 @@ BOOST_AUTO_TEST_CASE(reusing_memory) } )"; compileAndRun(sourceCode, 0, "Main"); - BOOST_REQUIRE(callContractFunction("f(uint256)", 0x34) == encodeArgs(dev::sha3(dev::toBigEndian(u256(0x34))))); + BOOST_REQUIRE(callContractFunction("f(uint256)", 0x34) == encodeArgs(dev::keccak256(dev::toBigEndian(u256(0x34))))); } BOOST_AUTO_TEST_CASE(return_string) @@ -5586,6 +5666,120 @@ BOOST_AUTO_TEST_CASE(accessor_for_const_state_variable) BOOST_CHECK(callContractFunction("ticketPrice()") == encodeArgs(u256(555))); } +BOOST_AUTO_TEST_CASE(state_variable_under_contract_name) +{ + char const* text = R"( + contract Scope { + uint stateVar = 42; + + function getStateVar() constant returns (uint stateVar) { + stateVar = Scope.stateVar; + } + } + )"; + compileAndRun(text); + BOOST_CHECK(callContractFunction("getStateVar()") == encodeArgs(u256(42))); +} + +BOOST_AUTO_TEST_CASE(state_variable_local_variable_mixture) +{ + char const* sourceCode = R"( + contract A { + uint x = 1; + uint y = 2; + function a() returns (uint x) { + x = A.y; + } + } + )"; + + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(2))); +} + +BOOST_AUTO_TEST_CASE(inherited_function) { + char const* sourceCode = R"( + contract A { function f() internal returns (uint) { return 1; } } + contract B is A { + function f() internal returns (uint) { return 2; } + function g() returns (uint) { + return A.f(); + } + } + )"; + + compileAndRun(sourceCode, 0, "B"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(1))); +} + +BOOST_AUTO_TEST_CASE(inherited_function_from_a_library) { + char const* sourceCode = R"( + library A { function f() internal returns (uint) { return 1; } } + contract B { + function f() internal returns (uint) { return 2; } + function g() returns (uint) { + return A.f(); + } + } + )"; + + compileAndRun(sourceCode, 0, "B"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(1))); +} + +BOOST_AUTO_TEST_CASE(inherited_constant_state_var) +{ + char const* sourceCode = R"( + contract A { + uint constant x = 7; + } + contract B is A { + function f() returns (uint) { + return A.x; + } + } + )"; + + compileAndRun(sourceCode, 0, "B"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7))); +} + +BOOST_AUTO_TEST_CASE(multiple_inherited_state_vars) +{ + char const* sourceCode = R"( + contract A { + uint x = 7; + } + contract B { + uint x = 9; + } + contract C is A, B { + function a() returns (uint) { + return A.x; + } + function b() returns (uint) { + return B.x; + } + function a_set(uint _x) returns (uint) { + A.x = _x; + return 1; + } + function b_set(uint _x) returns (uint) { + B.x = _x; + return 1; + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(7))); + BOOST_CHECK(callContractFunction("b()") == encodeArgs(u256(9))); + BOOST_CHECK(callContractFunction("a_set(uint256)", u256(1)) == encodeArgs(u256(1))); + BOOST_CHECK(callContractFunction("b_set(uint256)", u256(3)) == encodeArgs(u256(1))); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(1))); + BOOST_CHECK(callContractFunction("b()") == encodeArgs(u256(3))); +} + BOOST_AUTO_TEST_CASE(constant_string_literal) { char const* sourceCode = R"( @@ -5825,6 +6019,48 @@ BOOST_AUTO_TEST_CASE(using_library_structs) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7), u256(8))); } +BOOST_AUTO_TEST_CASE(library_struct_as_an_expression) +{ + char const* sourceCode = R"( + library Arst { + struct Foo { + int Things; + int Stuff; + } + } + + contract Tsra { + function f() returns(uint) { + Arst.Foo; + return 1; + } + } + )"; + compileAndRun(sourceCode, 0, "Tsra"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(1))); +} + +BOOST_AUTO_TEST_CASE(library_enum_as_an_expression) +{ + char const* sourceCode = R"( + library Arst { + enum Foo { + Things, + Stuff + } + } + + contract Tsra { + function f() returns(uint) { + Arst.Foo; + return 1; + } + } + )"; + compileAndRun(sourceCode, 0, "Tsra"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(1))); +} + BOOST_AUTO_TEST_CASE(short_strings) { // This test verifies that the byte array encoding that combines length and data works @@ -7231,6 +7467,72 @@ BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call) BOOST_CHECK(callContractFunction("f(address)", cAddrOpt) == encodeArgs(u256(7))); } +BOOST_AUTO_TEST_CASE(shift_constant_left) +{ + char const* sourceCode = R"( + contract C { + uint public a = 0x42 << 8; + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(0x4200))); +} + +BOOST_AUTO_TEST_CASE(shift_negative_constant_left) +{ + char const* sourceCode = R"( + contract C { + int public a = -0x42 << 8; + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(-0x4200))); +} + +BOOST_AUTO_TEST_CASE(shift_constant_right) +{ + char const* sourceCode = R"( + contract C { + uint public a = 0x4200 >> 8; + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(0x42))); +} + +BOOST_AUTO_TEST_CASE(shift_negative_constant_right) +{ + char const* sourceCode = R"( + contract C { + int public a = -0x4200 >> 8; + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(-0x42))); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_in_modifiers) +{ + char const* sourceCode = R"( + contract C { + modifier m { + uint a = 1; + assembly { + a := 2 + } + if (a != 2) + throw; + _; + } + function f() m returns (bool) { + return true; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(true)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityExecutionFramework.h b/test/libsolidity/SolidityExecutionFramework.h index 6cf7e0ee..7d44edaf 100644 --- a/test/libsolidity/SolidityExecutionFramework.h +++ b/test/libsolidity/SolidityExecutionFramework.h @@ -39,6 +39,7 @@ namespace dev { namespace solidity { + using rational = boost::rational<dev::bigint>; /// An Ethereum address: 20 bytes. /// @NOTE This is not endian-specific; it's just a bunch of bytes. using Address = h160; @@ -105,7 +106,7 @@ public: template <class... Args> bytes const& callContractFunctionWithValue(std::string _sig, u256 const& _value, Args const&... _arguments) { - FixedHash<4> hash(dev::sha3(_sig)); + FixedHash<4> hash(dev::keccak256(_sig)); sendMessage(hash.asBytes() + encodeArgs(_arguments...), false, _value); return m_output; } @@ -155,6 +156,14 @@ public: static bytes encode(char const* _value) { return encode(std::string(_value)); } static bytes encode(byte _value) { return bytes(31, 0) + bytes{_value}; } static bytes encode(u256 const& _value) { return toBigEndian(_value); } + /// @returns the fixed-point encoding of a rational number with a given + /// number of fractional bits. + static bytes encode(std::pair<rational, int> const& _valueAndPrecision) + { + rational const& value = _valueAndPrecision.first; + int fractionalBits = _valueAndPrecision.second; + return encode(u256((value.numerator() << fractionalBits) / value.denominator())); + } static bytes encode(h256 const& _value) { return _value.asBytes(); } static bytes encode(bytes const& _value, bool _padLeft = true) { @@ -186,7 +195,6 @@ public: { return encodeArgs(u256(0x20), u256(_arg.size()), _arg); } - class ContractInterface { public: diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index b8c64336..9fe91cca 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -154,7 +154,7 @@ static FunctionTypePointer retrieveFunctionBySignature( std::string const& _signature ) { - FixedHash<4> hash(dev::sha3(_signature)); + FixedHash<4> hash(dev::keccak256(_signature)); return _contract->interfaceFunctions()[hash]; } @@ -854,6 +854,23 @@ BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion) BOOST_CHECK(expectError(text) == Error::Type::TypeError); } +BOOST_AUTO_TEST_CASE(super_excludes_current_contract) +{ + char const* text = R"( + contract A { + function b() {} + } + + contract B is A { + function f() { + super.f(); + } + } + )"; + + BOOST_CHECK(expectError(text) == Error::Type::TypeError); +} + BOOST_AUTO_TEST_CASE(function_modifier_invocation) { char const* text = R"( @@ -1019,6 +1036,19 @@ 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 returns (uint stateVar) { + stateVar = Scope.stateVar; // should fail. + } + } + )"; + BOOST_CHECK(expectError(text) == Error::Type::TypeError); +} + + BOOST_AUTO_TEST_CASE(base_class_state_variable_accessor) { // test for issue #1126 https://github.com/ethereum/cpp-ethereum/issues/1126 @@ -1439,6 +1469,21 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access) BOOST_CHECK(expectError(text) == Error::Type::TypeError); } +BOOST_AUTO_TEST_CASE(enum_invalid_direct_member_access) +{ + char const* text = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test() + { + choices = Sit; + } + ActionChoices choices; + } + )"; + BOOST_CHECK(expectError(text) == Error::Type::DeclarationError); +} + BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay) { char const* text = R"( @@ -1500,6 +1545,23 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values) BOOST_CHECK(expectError(text) == Error::Type::DeclarationError); } +BOOST_AUTO_TEST_CASE(enum_name_resolution_under_current_contract_name) +{ + char const* text = R"( + contract A { + enum Foo { + First, + Second + } + + function a() { + A.Foo; + } + } + )"; + BOOST_CHECK(success(text)); +} + BOOST_AUTO_TEST_CASE(private_visibility) { char const* sourceCode = R"( @@ -4020,6 +4082,169 @@ BOOST_AUTO_TEST_CASE(invalid_array_as_statement) BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); } +BOOST_AUTO_TEST_CASE(using_directive_for_missing_selftype) +{ + char const* text = R"( + library B { + function b() {} + } + + contract A { + using B for bytes; + + function a() { + bytes memory x; + x.b(); + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); +} + +BOOST_AUTO_TEST_CASE(invalid_fixed_point_literal) +{ + char const* text = R"( + contract A { + function a() { + .8E0; + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); +} + +BOOST_AUTO_TEST_CASE(shift_constant_left_negative_rvalue) +{ + char const* text = R"( + contract C { + uint public a = 0x42 << -8; + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); +} + +BOOST_AUTO_TEST_CASE(shift_constant_right_negative_rvalue) +{ + char const* text = R"( + contract C { + uint public a = 0x42 >> -8; + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); +} + +BOOST_AUTO_TEST_CASE(shift_constant_left_excessive_rvalue) +{ + char const* text = R"( + contract C { + uint public a = 0x42 << 0x100000000; + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); +} + +BOOST_AUTO_TEST_CASE(shift_constant_right_excessive_rvalue) +{ + char const* text = R"( + contract C { + uint public a = 0x42 >> 0x100000000; + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_unbalanced_positive_stack) +{ + char const* text = R"( + contract test { + function f() { + assembly { + 1 + } + } + } + )"; + BOOST_CHECK(expectError(text, true) == Error::Type::Warning); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_unbalanced_negative_stack) +{ + char const* text = R"( + contract test { + function f() { + assembly { + pop + } + } + } + )"; + BOOST_CHECK(expectError(text, true) == Error::Type::Warning); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_in_modifier) +{ + char const* text = R"( + contract test { + modifier m { + uint a = 1; + assembly { + a := 2 + } + _; + } + function f() m { + } + } + )"; + BOOST_CHECK(success(text)); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_storage) +{ + char const* text = R"( + contract test { + uint x = 1; + function f() { + assembly { + x := 2 + } + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::DeclarationError); +} + +BOOST_AUTO_TEST_CASE(inline_assembly_storage_in_modifiers) +{ + char const* text = R"( + contract test { + uint x = 1; + modifier m { + assembly { + x := 2 + } + _; + } + function f() m { + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::DeclarationError); +} + +BOOST_AUTO_TEST_CASE(invalid_mobile_type) +{ + char const* text = R"( + contract C { + function f() { + // Invalid number + [1, 78901234567890123456789012345678901234567890123456789345678901234567890012345678012345678901234567]; + } + } + )"; + BOOST_CHECK(expectError(text, false) == Error::Type::TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 206f23fb..562b7859 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -805,7 +805,7 @@ BOOST_AUTO_TEST_CASE(cse_empty_sha3) Instruction::SHA3 }; checkCSE(input, { - u256(sha3(bytesConstRef())) + u256(dev::keccak256(bytesConstRef())) }); } @@ -823,7 +823,7 @@ BOOST_AUTO_TEST_CASE(cse_partial_sha3) u256(0xabcd) << (256 - 16), u256(0), Instruction::MSTORE, - u256(sha3(bytes{0xab, 0xcd})) + u256(dev::keccak256(bytes{0xab, 0xcd})) }); } |