aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libevmasm/Assembly.cpp2
-rw-r--r--libsolidity/ast/Types.cpp41
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp2
-rw-r--r--test/libsolidity/ASTJSON.cpp17
4 files changed, 41 insertions, 21 deletions
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp
index a813a3a7..a3037456 100644
--- a/libevmasm/Assembly.cpp
+++ b/libevmasm/Assembly.cpp
@@ -81,7 +81,7 @@ string Assembly::out() const
unsigned Assembly::bytesRequired(unsigned subTagSize) const
{
- for (unsigned tagSize = subTagSize;; ++tagSize)
+ for (unsigned tagSize = subTagSize; true; ++tagSize)
{
unsigned ret = 1;
for (auto const& i: m_data)
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 3a8fc075..4488398f 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -1827,23 +1827,28 @@ FunctionType::FunctionType(FunctionTypeName const& _typeName):
m_isPayable(_typeName.isPayable())
{
if (_typeName.isPayable())
+ {
solAssert(m_location == Location::External, "Internal payable function type used.");
+ solAssert(!m_isConstant, "Payable constant function");
+ }
for (auto const& t: _typeName.parameterTypes())
{
solAssert(t->annotation().type, "Type not set for parameter.");
- solAssert(
- m_location != Location::External || t->annotation().type->canBeUsedExternally(false),
- "Internal type used as parameter for external function."
- );
+ if (m_location == Location::External)
+ solAssert(
+ t->annotation().type->canBeUsedExternally(false),
+ "Internal type used as parameter for external function."
+ );
m_parameterTypes.push_back(t->annotation().type);
}
for (auto const& t: _typeName.returnParameterTypes())
{
solAssert(t->annotation().type, "Type not set for return parameter.");
- solAssert(
- m_location != Location::External || t->annotation().type->canBeUsedExternally(false),
- "Internal type used as return parameter for external function."
- );
+ if (m_location == Location::External)
+ solAssert(
+ t->annotation().type->canBeUsedExternally(false),
+ "Internal type used as return parameter for external function."
+ );
m_returnParameterTypes.push_back(t->annotation().type);
}
}
@@ -1941,17 +1946,21 @@ string FunctionType::toString(bool _short) const
string name = "function (";
for (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it)
name += (*it)->toString(_short) + (it + 1 == m_parameterTypes.end() ? "" : ",");
- name += ") ";
+ name += ")";
if (m_isConstant)
- name += "constant ";
+ name += " constant";
if (m_isPayable)
- name += "payable ";
+ name += " payable";
if (m_location == Location::External)
- name += "external ";
- name += "returns (";
- for (auto it = m_returnParameterTypes.begin(); it != m_returnParameterTypes.end(); ++it)
- name += (*it)->toString(_short) + (it + 1 == m_returnParameterTypes.end() ? "" : ",");
- return name + ")";
+ name += " external";
+ if (!m_returnParameterTypes.empty())
+ {
+ name += " returns (";
+ for (auto it = m_returnParameterTypes.begin(); it != m_returnParameterTypes.end(); ++it)
+ name += (*it)->toString(_short) + (it + 1 == m_returnParameterTypes.end() ? "" : ",");
+ name += ")";
+ }
+ return name;
}
unsigned FunctionType::calldataEncodedSize(bool _padded) const
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index 1e819ed4..bfe5386b 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -138,7 +138,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound
dynamic_cast<FunctionType const&>(_type).location() == FunctionType::Location::External
)
{
- solAssert(_padToWordBoundaries, "Non-padded store for function not implemented.");
+ solUnimplementedAssert(_padToWordBoundaries, "Non-padded store for function not implemented.");
combineExternalFunctionType(true);
m_context << Instruction::DUP2 << Instruction::MSTORE;
m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD;
diff --git a/test/libsolidity/ASTJSON.cpp b/test/libsolidity/ASTJSON.cpp
index fd7c21b8..b88218e7 100644
--- a/test/libsolidity/ASTJSON.cpp
+++ b/test/libsolidity/ASTJSON.cpp
@@ -200,7 +200,10 @@ BOOST_AUTO_TEST_CASE(non_utf8)
BOOST_AUTO_TEST_CASE(function_type)
{
CompilerStack c;
- c.addSource("a", "contract C { function f(function() external payable constant returns (uint) x) {} }");
+ c.addSource("a",
+ "contract C { function f(function() external payable returns (uint) x) "
+ "returns (function() external constant returns (uint)) {} }"
+ );
c.parse();
map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1;
@@ -210,11 +213,19 @@ BOOST_AUTO_TEST_CASE(function_type)
Json::Value argument = fun["children"][0]["children"][0];
BOOST_CHECK_EQUAL(argument["name"], "VariableDeclaration");
BOOST_CHECK_EQUAL(argument["attributes"]["name"], "x");
- BOOST_CHECK_EQUAL(argument["attributes"]["type"], "function () constant payable external returns (uint256)");
+ BOOST_CHECK_EQUAL(argument["attributes"]["type"], "function () payable external returns (uint256)");
Json::Value funType = argument["children"][0];
- BOOST_CHECK_EQUAL(funType["attributes"]["constant"], true);
+ BOOST_CHECK_EQUAL(funType["attributes"]["constant"], false);
BOOST_CHECK_EQUAL(funType["attributes"]["payable"], true);
BOOST_CHECK_EQUAL(funType["attributes"]["visibility"], "external");
+ Json::Value retval = fun["children"][1]["children"][0];
+ BOOST_CHECK_EQUAL(retval["name"], "VariableDeclaration");
+ BOOST_CHECK_EQUAL(retval["attributes"]["name"], "");
+ BOOST_CHECK_EQUAL(retval["attributes"]["type"], "function () constant external returns (uint256)");
+ funType = retval["children"][0];
+ BOOST_CHECK_EQUAL(funType["attributes"]["constant"], true);
+ BOOST_CHECK_EQUAL(funType["attributes"]["payable"], false);
+ BOOST_CHECK_EQUAL(funType["attributes"]["visibility"], "external");
}
BOOST_AUTO_TEST_SUITE_END()