aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGav Wood <g@ethdev.com>2014-12-17 20:49:31 +0800
committerGav Wood <g@ethdev.com>2014-12-17 20:49:31 +0800
commit79341771f76135ddbe6e3053c38b3e3d132247da (patch)
tree7a122db415b4692658bead4cb32cf5f308e1b522
parent36532d9ab4521fb3e7bb7922afb61d93180ed1e2 (diff)
parent5e148ae4b60efde4bfc87de726cf2f817df8a951 (diff)
downloaddexon-solidity-79341771f76135ddbe6e3053c38b3e3d132247da.tar.gz
dexon-solidity-79341771f76135ddbe6e3053c38b3e3d132247da.tar.zst
dexon-solidity-79341771f76135ddbe6e3053c38b3e3d132247da.zip
Merge pull request #636 from chriseth/sol_fix_foreignFunctions
Fix: Resolve function types of all contracts before checking types inside functions.
-rw-r--r--solidityCompiler.cpp8
-rw-r--r--solidityExpressionCompiler.cpp7
-rw-r--r--solidityNameAndTypeResolution.cpp18
3 files changed, 30 insertions, 3 deletions
diff --git a/solidityCompiler.cpp b/solidityCompiler.cpp
index 1bdafc59..be2c8383 100644
--- a/solidityCompiler.cpp
+++ b/solidityCompiler.cpp
@@ -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
diff --git a/solidityExpressionCompiler.cpp b/solidityExpressionCompiler.cpp
index c05db25d..2bdc3842 100644
--- a/solidityExpressionCompiler.cpp
+++ b/solidityExpressionCompiler.cpp
@@ -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);
diff --git a/solidityNameAndTypeResolution.cpp b/solidityNameAndTypeResolution.cpp
index 0ea6e51b..0bda0a1f 100644
--- a/solidityNameAndTypeResolution.cpp
+++ b/solidityNameAndTypeResolution.cpp
@@ -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()
}