Merge pull request #636 from chriseth/sol_fix_foreignFunctions

Fix: Resolve function types of all contracts before checking types inside functions.
This commit is contained in:
Gav Wood 2014-12-17 13:49:31 +01:00
commit 79341771f7
3 changed files with 30 additions and 3 deletions

View File

@ -52,9 +52,13 @@ bytes compileContract(const string& _sourceCode)
resolver.registerDeclarations(*sourceUnit);
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract));
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
Compiler compiler;
// clang requires explicit initialization of map

View File

@ -95,8 +95,13 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _
resolver.registerDeclarations(*sourceUnit);
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract));
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
FirstExpressionExtractor extractor(*contract);
BOOST_REQUIRE(extractor.getExpression() != nullptr);

View File

@ -47,6 +47,9 @@ void parseTextAndResolveNames(std::string const& _source)
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
resolver.resolveNamesAndTypes(*contract);
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
resolver.checkTypeRequirements(*contract);
}
}
@ -293,6 +296,21 @@ BOOST_AUTO_TEST_CASE(returns_in_constructor)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(forward_function_reference)
{
char const* text = "contract First {\n"
" function fun() returns (bool ret) {\n"
" return Second(1).fun(1, true, 3) > 0;\n"
" }\n"
"}\n"
"contract Second {\n"
" function fun(uint a, bool b, uint c) returns (uint ret) {\n"
" if (First(2).fun() == true) return 1;\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_SUITE_END()
}