aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp154
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp199
2 files changed, 292 insertions, 61 deletions
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index db7f59ee..d0c5285c 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -1950,6 +1950,87 @@ BOOST_AUTO_TEST_CASE(ripemd)
testContractAgainstCpp("a(bytes32)", f, u256(-1));
}
+BOOST_AUTO_TEST_CASE(packed_keccak256)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function a(bytes32 input) returns (bytes32 hash) {
+ var b = 65536;
+ uint c = 256;
+ return keccak256(8, input, b, input, c);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ auto f = [&](u256 const& _x) -> u256
+ {
+ return dev::keccak256(
+ toCompactBigEndian(unsigned(8)) +
+ toBigEndian(_x) +
+ toCompactBigEndian(unsigned(65536)) +
+ toBigEndian(_x) +
+ toBigEndian(u256(256))
+ );
+ };
+ testContractAgainstCpp("a(bytes32)", f, u256(4));
+ testContractAgainstCpp("a(bytes32)", f, u256(5));
+ testContractAgainstCpp("a(bytes32)", f, u256(-1));
+}
+
+BOOST_AUTO_TEST_CASE(packed_sha256)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function a(bytes32 input) returns (bytes32 hash) {
+ var b = 65536;
+ uint c = 256;
+ return sha256(8, input, b, input, c);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ auto f = [&](u256 const& _x) -> bytes
+ {
+ if (_x == u256(4))
+ return fromHex("804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac");
+ if (_x == u256(5))
+ return fromHex("e94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0");
+ if (_x == u256(-1))
+ return fromHex("f14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7");
+ return fromHex("");
+ };
+ testContractAgainstCpp("a(bytes32)", f, u256(4));
+ testContractAgainstCpp("a(bytes32)", f, u256(5));
+ testContractAgainstCpp("a(bytes32)", f, u256(-1));
+}
+
+BOOST_AUTO_TEST_CASE(packed_ripemd160)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function a(bytes32 input) returns (bytes32 hash) {
+ var b = 65536;
+ uint c = 256;
+ return ripemd160(8, input, b, input, c);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ auto f = [&](u256 const& _x) -> bytes
+ {
+ if (_x == u256(4))
+ return fromHex("f93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000");
+ if (_x == u256(5))
+ return fromHex("04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000");
+ if (_x == u256(-1))
+ return fromHex("c0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000");
+ return fromHex("");
+ };
+ testContractAgainstCpp("a(bytes32)", f, u256(4));
+ testContractAgainstCpp("a(bytes32)", f, u256(5));
+ testContractAgainstCpp("a(bytes32)", f, u256(-1));
+}
+
BOOST_AUTO_TEST_CASE(ecrecover)
{
char const* sourceCode = R"(
@@ -2318,21 +2399,6 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic)
BOOST_REQUIRE(callContractFunction("checkState()") == encodeArgs(false, 20 - 5));
}
-BOOST_AUTO_TEST_CASE(gas_for_builtin)
-{
- char const* sourceCode = R"(
- contract Contract {
- function test(uint g) returns (bytes32 data, bool flag) {
- data = ripemd160.gas(g)("abc");
- flag = true;
- }
- }
- )";
- compileAndRun(sourceCode);
- BOOST_CHECK(callContractFunction("test(uint256)", 500) == bytes());
- BOOST_CHECK(callContractFunction("test(uint256)", 800) == encodeArgs(u256("0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc000000000000000000000000"), true));
-}
-
BOOST_AUTO_TEST_CASE(value_complex)
{
char const* sourceCode = R"(
@@ -9816,6 +9882,64 @@ BOOST_AUTO_TEST_CASE(inlineasm_empty_let)
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0), u256(0)));
}
+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 constant returns (bool) {
+ return address(0x4242).call();
+ }
+ function g() external constant returns (bool) {
+ return address(0x4242).callcode();
+ }
+ function h() external constant returns (bool) {
+ return address(0x4242).delegatecall();
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("h()") == encodeArgs(u256(1)));
+}
+
+BOOST_AUTO_TEST_CASE(delegatecall_return_value)
+{
+ char const* sourceCode = R"DELIMITER(
+ contract C {
+ uint value;
+ function set(uint _value) external {
+ value = _value;
+ }
+ function get() external constant returns (uint) {
+ return value;
+ }
+ function get_delegated() external constant returns (bool) {
+ return this.delegatecall(bytes4(sha3("get()")));
+ }
+ function assert0() external constant {
+ assert(value == 0);
+ }
+ function assert0_delegated() external constant returns (bool) {
+ return this.delegatecall(bytes4(sha3("assert0()")));
+ }
+ }
+ )DELIMITER";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("get()") == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("assert0_delegated()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("get_delegated()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("set(uint256)", u256(1)) == encodeArgs());
+ BOOST_CHECK(callContractFunction("get()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("assert0_delegated()") == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("get_delegated()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("set(uint256)", u256(42)) == encodeArgs());
+ BOOST_CHECK(callContractFunction("get()") == encodeArgs(u256(42)));
+ BOOST_CHECK(callContractFunction("assert0_delegated()") == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("get_delegated()") == encodeArgs(u256(1)));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index cd922cc8..2fbc6ac8 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -624,7 +624,7 @@ BOOST_AUTO_TEST_CASE(function_no_implementation)
std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
ContractDefinition* contract = dynamic_cast<ContractDefinition*>(nodes[1].get());
BOOST_REQUIRE(contract);
- BOOST_CHECK(!contract->annotation().isFullyImplemented);
+ BOOST_CHECK(!contract->annotation().unimplementedFunctions.empty());
BOOST_CHECK(!contract->definedFunctions()[0]->isImplemented());
}
@@ -640,10 +640,10 @@ BOOST_AUTO_TEST_CASE(abstract_contract)
ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get());
ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());
BOOST_REQUIRE(base);
- BOOST_CHECK(!base->annotation().isFullyImplemented);
+ BOOST_CHECK(!base->annotation().unimplementedFunctions.empty());
BOOST_CHECK(!base->definedFunctions()[0]->isImplemented());
BOOST_REQUIRE(derived);
- BOOST_CHECK(derived->annotation().isFullyImplemented);
+ BOOST_CHECK(derived->annotation().unimplementedFunctions.empty());
BOOST_CHECK(derived->definedFunctions()[0]->isImplemented());
}
@@ -659,9 +659,9 @@ BOOST_AUTO_TEST_CASE(abstract_contract_with_overload)
ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get());
ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());
BOOST_REQUIRE(base);
- BOOST_CHECK(!base->annotation().isFullyImplemented);
+ BOOST_CHECK(!base->annotation().unimplementedFunctions.empty());
BOOST_REQUIRE(derived);
- BOOST_CHECK(!derived->annotation().isFullyImplemented);
+ BOOST_CHECK(!derived->annotation().unimplementedFunctions.empty());
}
BOOST_AUTO_TEST_CASE(create_abstract_contract)
@@ -677,44 +677,6 @@ BOOST_AUTO_TEST_CASE(create_abstract_contract)
CHECK_ERROR(text, TypeError, "");
}
-BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_optional)
-{
- ASTPointer<SourceUnit> sourceUnit;
- char const* text = R"(
- contract BaseBase { function BaseBase(uint j); }
- contract base is BaseBase { function foo(); }
- contract derived is base {
- function derived(uint i) BaseBase(i){}
- function foo() {}
- }
- )";
- ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name resolving failed");
- std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
- BOOST_CHECK_EQUAL(nodes.size(), 4);
- ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[3].get());
- BOOST_REQUIRE(derived);
- BOOST_CHECK(!derived->annotation().isFullyImplemented);
-}
-
-BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_not_provided)
-{
- ASTPointer<SourceUnit> sourceUnit;
- char const* text = R"(
- contract BaseBase { function BaseBase(uint); }
- contract base is BaseBase { function foo(); }
- contract derived is base {
- function derived(uint) {}
- function foo() {}
- }
- )";
- ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name resolving failed");
- std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
- BOOST_CHECK_EQUAL(nodes.size(), 4);
- ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[3].get());
- BOOST_REQUIRE(derived);
- BOOST_CHECK(!derived->annotation().isFullyImplemented);
-}
-
BOOST_AUTO_TEST_CASE(redeclare_implemented_abstract_function_as_abstract)
{
ASTPointer<SourceUnit> sourceUnit;
@@ -738,7 +700,7 @@ BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)
BOOST_CHECK_EQUAL(nodes.size(), 3);
ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());
BOOST_REQUIRE(derived);
- BOOST_CHECK(!derived->annotation().isFullyImplemented);
+ BOOST_CHECK(!derived->annotation().unimplementedFunctions.empty());
}
BOOST_AUTO_TEST_CASE(function_canonical_signature)
@@ -5714,7 +5676,7 @@ BOOST_AUTO_TEST_CASE(interface_constructor)
function I();
}
)";
- CHECK_ERROR(text, TypeError, "Constructor cannot be defined in interfaces");
+ CHECK_ERROR_ALLOW_MULTI(text, TypeError, "Constructor cannot be defined in interfaces");
}
BOOST_AUTO_TEST_CASE(interface_functions)
@@ -6134,6 +6096,25 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_with_variables)
CHECK_WARNING(text, "shadows a builtin symbol");
}
+BOOST_AUTO_TEST_CASE(shadowing_builtins_with_storage_variables)
+{
+ char const* text = R"(
+ contract C {
+ uint msg;
+ }
+ )";
+ CHECK_WARNING(text, "shadows a builtin symbol");
+}
+
+BOOST_AUTO_TEST_CASE(shadowing_builtin_at_global_scope)
+{
+ char const* text = R"(
+ contract msg {
+ }
+ )";
+ CHECK_WARNING(text, "shadows a builtin symbol");
+}
+
BOOST_AUTO_TEST_CASE(shadowing_builtins_with_parameters)
{
char const* text = R"(
@@ -6190,6 +6171,28 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_ignores_constructor)
CHECK_SUCCESS_NO_WARNINGS(text);
}
+BOOST_AUTO_TEST_CASE(function_overload_is_not_shadowing)
+{
+ char const* text = R"(
+ contract C {
+ function f() {}
+ function f(uint) {}
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(function_override_is_not_shadowing)
+{
+ char const* text = R"(
+ contract D { function f() {} }
+ contract C is D {
+ function f(uint) {}
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
BOOST_AUTO_TEST_CASE(callable_crash)
{
char const* text = R"(
@@ -6437,7 +6440,7 @@ BOOST_AUTO_TEST_CASE(using_this_in_constructor)
CHECK_WARNING(text, "\"this\" used in constructor");
}
-BOOST_AUTO_TEST_CASE(do_not_crash_on_not_lalue)
+BOOST_AUTO_TEST_CASE(do_not_crash_on_not_lvalue)
{
// This checks for a bug that caused a crash because of continued analysis.
char const* text = R"(
@@ -6451,6 +6454,110 @@ BOOST_AUTO_TEST_CASE(do_not_crash_on_not_lalue)
CHECK_ERROR_ALLOW_MULTI(text, TypeError, "is not callable");
}
+BOOST_AUTO_TEST_CASE(builtin_reject_gas)
+{
+ char const* text = R"(
+ contract C {
+ function f() {
+ keccak256.gas();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"gas\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ sha256.gas();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"gas\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ ripemd160.gas();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"gas\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ ecrecover.gas();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"gas\" not found or not visible after argument-dependent lookup");
+}
+
+BOOST_AUTO_TEST_CASE(builtin_reject_value)
+{
+ char const* text = R"(
+ contract C {
+ function f() {
+ keccak256.value();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ sha256.value();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ ripemd160.value();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ ecrecover.value();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup");
+}
+
+BOOST_AUTO_TEST_CASE(constructor_without_implementation)
+{
+ char const* text = R"(
+ contract C {
+ function C();
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Constructor must be implemented if declared.");
+}
+
+BOOST_AUTO_TEST_CASE(library_function_without_implementation)
+{
+ char const* text = R"(
+ library L {
+ function f();
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+ text = R"(
+ library L {
+ function f() internal;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Internal library function must be implemented if declared.");
+ text = R"(
+ library L {
+ function f() private;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Internal library function must be implemented if declared.");
+}
+
BOOST_AUTO_TEST_SUITE_END()
}