Some more assertions and style changes.

This commit is contained in:
chriseth 2016-11-16 15:09:01 +01:00
parent 2defe4dcef
commit 2c14a96820
4 changed files with 41 additions and 21 deletions

View File

@ -81,7 +81,7 @@ string Assembly::out() const
unsigned Assembly::bytesRequired(unsigned subTagSize) const unsigned Assembly::bytesRequired(unsigned subTagSize) const
{ {
for (unsigned tagSize = subTagSize;; ++tagSize) for (unsigned tagSize = subTagSize; true; ++tagSize)
{ {
unsigned ret = 1; unsigned ret = 1;
for (auto const& i: m_data) for (auto const& i: m_data)

View File

@ -1827,23 +1827,28 @@ FunctionType::FunctionType(FunctionTypeName const& _typeName):
m_isPayable(_typeName.isPayable()) m_isPayable(_typeName.isPayable())
{ {
if (_typeName.isPayable()) if (_typeName.isPayable())
{
solAssert(m_location == Location::External, "Internal payable function type used."); solAssert(m_location == Location::External, "Internal payable function type used.");
solAssert(!m_isConstant, "Payable constant function");
}
for (auto const& t: _typeName.parameterTypes()) for (auto const& t: _typeName.parameterTypes())
{ {
solAssert(t->annotation().type, "Type not set for parameter."); solAssert(t->annotation().type, "Type not set for parameter.");
solAssert( if (m_location == Location::External)
m_location != Location::External || t->annotation().type->canBeUsedExternally(false), solAssert(
"Internal type used as parameter for external function." t->annotation().type->canBeUsedExternally(false),
); "Internal type used as parameter for external function."
);
m_parameterTypes.push_back(t->annotation().type); m_parameterTypes.push_back(t->annotation().type);
} }
for (auto const& t: _typeName.returnParameterTypes()) for (auto const& t: _typeName.returnParameterTypes())
{ {
solAssert(t->annotation().type, "Type not set for return parameter."); solAssert(t->annotation().type, "Type not set for return parameter.");
solAssert( if (m_location == Location::External)
m_location != Location::External || t->annotation().type->canBeUsedExternally(false), solAssert(
"Internal type used as return parameter for external function." t->annotation().type->canBeUsedExternally(false),
); "Internal type used as return parameter for external function."
);
m_returnParameterTypes.push_back(t->annotation().type); m_returnParameterTypes.push_back(t->annotation().type);
} }
} }
@ -1941,17 +1946,21 @@ string FunctionType::toString(bool _short) const
string name = "function ("; string name = "function (";
for (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it) for (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it)
name += (*it)->toString(_short) + (it + 1 == m_parameterTypes.end() ? "" : ","); name += (*it)->toString(_short) + (it + 1 == m_parameterTypes.end() ? "" : ",");
name += ") "; name += ")";
if (m_isConstant) if (m_isConstant)
name += "constant "; name += " constant";
if (m_isPayable) if (m_isPayable)
name += "payable "; name += " payable";
if (m_location == Location::External) if (m_location == Location::External)
name += "external "; name += " external";
name += "returns ("; if (!m_returnParameterTypes.empty())
for (auto it = m_returnParameterTypes.begin(); it != m_returnParameterTypes.end(); ++it) {
name += (*it)->toString(_short) + (it + 1 == m_returnParameterTypes.end() ? "" : ","); name += " returns (";
return name + ")"; 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 unsigned FunctionType::calldataEncodedSize(bool _padded) const

View File

@ -138,7 +138,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound
dynamic_cast<FunctionType const&>(_type).location() == FunctionType::Location::External 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); combineExternalFunctionType(true);
m_context << Instruction::DUP2 << Instruction::MSTORE; m_context << Instruction::DUP2 << Instruction::MSTORE;
m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD; m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD;

View File

@ -200,7 +200,10 @@ BOOST_AUTO_TEST_CASE(non_utf8)
BOOST_AUTO_TEST_CASE(function_type) BOOST_AUTO_TEST_CASE(function_type)
{ {
CompilerStack c; 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(); c.parse();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
@ -210,11 +213,19 @@ BOOST_AUTO_TEST_CASE(function_type)
Json::Value argument = fun["children"][0]["children"][0]; Json::Value argument = fun["children"][0]["children"][0];
BOOST_CHECK_EQUAL(argument["name"], "VariableDeclaration"); BOOST_CHECK_EQUAL(argument["name"], "VariableDeclaration");
BOOST_CHECK_EQUAL(argument["attributes"]["name"], "x"); 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]; 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"]["payable"], true);
BOOST_CHECK_EQUAL(funType["attributes"]["visibility"], "external"); 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() BOOST_AUTO_TEST_SUITE_END()