diff options
author | chriseth <chris@ethereum.org> | 2016-08-26 16:11:34 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-26 16:11:34 +0800 |
commit | d209e65b1d9ce3f49821970e96e027ba5243e386 (patch) | |
tree | b08cb8a4cb5fd592e67bd4a25de92980a63eec16 | |
parent | 3eeefb5c9e27c9401184cc28cf72bfd37ac35785 (diff) | |
parent | ce42114c4170406f1f7ce67d57429ff3e7b73079 (diff) | |
download | dexon-solidity-d209e65b1d9ce3f49821970e96e027ba5243e386.tar.gz dexon-solidity-d209e65b1d9ce3f49821970e96e027ba5243e386.tar.zst dexon-solidity-d209e65b1d9ce3f49821970e96e027ba5243e386.zip |
Merge pull request #949 from chriseth/fallbackReturn
Disallow fallback function to return values.
-rw-r--r-- | docs/contracts.rst | 3 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 2 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 18 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 10 |
4 files changed, 23 insertions, 10 deletions
diff --git a/docs/contracts.rst b/docs/contracts.rst index e9fc4526..85592f5d 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -425,7 +425,8 @@ Fallback Function ***************** A contract can have exactly one unnamed function. This function cannot have -arguments and is executed on a call to the contract if none of the other +arguments and cannot return anything. +It is executed on a call to the contract if none of the other functions matches the given function identifier (or if no data was supplied at all). diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 6b2c1cb8..235fcabd 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -94,6 +94,8 @@ bool TypeChecker::visit(ContractDefinition const& _contract) fallbackFunction = function; if (!fallbackFunction->parameters().empty()) typeError(fallbackFunction->parameterList().location(), "Fallback function cannot take parameters."); + if (!fallbackFunction->returnParameters().empty()) + typeError(fallbackFunction->returnParameterList()->location(), "Fallback function cannot return values."); } } if (!function->isImplemented()) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 45f6aec5..f3cd387a 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -2529,13 +2529,13 @@ BOOST_AUTO_TEST_CASE(fallback_function) char const* sourceCode = R"( contract A { uint data; - function() returns (uint r) { data = 1; return 2; } + function() { data = 1; } function getData() returns (uint r) { return data; } } )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("getData()") == encodeArgs(0)); - BOOST_CHECK(callContractFunction("") == encodeArgs(2)); + BOOST_CHECK(callContractFunction("") == encodeArgs()); BOOST_CHECK(callContractFunction("getData()") == encodeArgs(1)); } @@ -2544,14 +2544,14 @@ BOOST_AUTO_TEST_CASE(inherited_fallback_function) char const* sourceCode = R"( contract A { uint data; - function() returns (uint r) { data = 1; return 2; } + function() { data = 1; } function getData() returns (uint r) { return data; } } contract B is A {} )"; compileAndRun(sourceCode, 0, "B"); BOOST_CHECK(callContractFunction("getData()") == encodeArgs(0)); - BOOST_CHECK(callContractFunction("") == encodeArgs(2)); + BOOST_CHECK(callContractFunction("") == encodeArgs()); BOOST_CHECK(callContractFunction("getData()") == encodeArgs(1)); } @@ -3002,13 +3002,13 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory) { char const* sourceCode = R"( contract C { - function() returns (bytes32) { + function f() returns (bytes32) { return sha3("abc", msg.data); } } )"; compileAndRun(sourceCode); - bytes calldata1 = bytes(61, 0x22) + bytes(12, 0x12); + bytes calldata1 = FixedHash<4>(dev::sha3("f()")).asBytes() + bytes(61, 0x22) + bytes(12, 0x12); sendMessage(calldata1, false); BOOST_CHECK(m_output == encodeArgs(dev::sha3(bytes{'a', 'b', 'c'} + calldata1))); } @@ -3024,7 +3024,7 @@ BOOST_AUTO_TEST_CASE(call_forward_bytes) contract sender { function sender() { rec = new receiver(); } function() { savedData = msg.data; } - function forward() returns (bool) { rec.call(savedData); return true; } + function forward() returns (bool) { !rec.call(savedData); return true; } function clear() returns (bool) { delete savedData; return true; } function val() returns (uint) { return rec.received(); } receiver rec; @@ -4342,12 +4342,12 @@ BOOST_AUTO_TEST_CASE(external_types_in_calls) y = this.t1(C1(7)); } function t1(C1 a) returns (C1) { return a; } - function() returns (C1) { return C1(9); } + function t2() returns (C1) { return C1(9); } } )"; compileAndRun(sourceCode, 0, "C"); BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(9), u256(7))); - BOOST_CHECK(callContractFunction("nonexisting") == encodeArgs(u256(9))); + BOOST_CHECK(callContractFunction("t2()") == encodeArgs(u256(9))); } BOOST_AUTO_TEST_CASE(proper_order_of_overwriting_of_attributes) diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index e9da390c..f0ab07c5 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1102,6 +1102,16 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_arguments) BOOST_CHECK(expectError(text) == Error::Type::TypeError); } +BOOST_AUTO_TEST_CASE(fallback_function_with_return_parameters) +{ + char const* text = R"( + contract C { + function() returns (uint) { } + } + )"; + BOOST_CHECK(expectError(text) == Error::Type::TypeError); +} + BOOST_AUTO_TEST_CASE(fallback_function_twice) { char const* text = R"( |