diff options
-rw-r--r-- | libevmasm/Assembly.cpp | 2 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 41 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerUtils.cpp | 2 | ||||
-rw-r--r-- | test/libsolidity/ASTJSON.cpp | 17 |
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() |