aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2016-08-26 16:11:34 +0800
committerGitHub <noreply@github.com>2016-08-26 16:11:34 +0800
commitd209e65b1d9ce3f49821970e96e027ba5243e386 (patch)
treeb08cb8a4cb5fd592e67bd4a25de92980a63eec16
parent3eeefb5c9e27c9401184cc28cf72bfd37ac35785 (diff)
parentce42114c4170406f1f7ce67d57429ff3e7b73079 (diff)
downloaddexon-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.rst3
-rw-r--r--libsolidity/analysis/TypeChecker.cpp2
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp18
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp10
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"(