aboutsummaryrefslogtreecommitdiffstats
path: root/SolidityNameAndTypeResolution.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SolidityNameAndTypeResolution.cpp')
-rw-r--r--SolidityNameAndTypeResolution.cpp102
1 files changed, 100 insertions, 2 deletions
diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp
index 591cf053..3bec70a2 100644
--- a/SolidityNameAndTypeResolution.cpp
+++ b/SolidityNameAndTypeResolution.cpp
@@ -28,6 +28,7 @@
#include <libsolidity/Parser.h>
#include <libsolidity/NameAndTypeResolver.h>
#include <libsolidity/Exceptions.h>
+#include <libsolidity/GlobalContext.h>
#include "TestHelper.h"
using namespace std;
@@ -48,16 +49,28 @@ ASTPointer<SourceUnit> parseTextAndResolveNames(std::string const& _source)
ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source)));
NameAndTypeResolver resolver({});
resolver.registerDeclarations(*sourceUnit);
+ std::shared_ptr<GlobalContext> globalContext = make_shared<GlobalContext>();
+
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
+ {
+ globalContext->setCurrentContract(*contract);
+ resolver.updateDeclaration(*globalContext->getCurrentThis());
+ resolver.updateDeclaration(*globalContext->getCurrentSuper());
resolver.resolveNamesAndTypes(*contract);
+ }
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
+ {
+ globalContext->setCurrentContract(*contract);
+ resolver.updateDeclaration(*globalContext->getCurrentThis());
resolver.checkTypeRequirements(*contract);
+ }
return sourceUnit;
}
+
static ContractDefinition const* retrieveContract(ASTPointer<SourceUnit> _source, unsigned index)
{
ContractDefinition* contract;
@@ -359,7 +372,7 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature)
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
auto functions = contract->getDefinedFunctions();
- BOOST_CHECK_EQUAL("foo(uint256,uint64,bool)", functions[0]->getCanonicalSignature());
+ BOOST_CHECK_EQUAL("foo(uint256,uint64,bool)", functions[0]->externalSignature());
}
}
@@ -376,8 +389,93 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases)
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
auto functions = contract->getDefinedFunctions();
- BOOST_CHECK_EQUAL("boo(uint256,bytes32,address)", functions[0]->getCanonicalSignature());
+ if (functions.empty())
+ continue;
+ BOOST_CHECK_EQUAL("boo(uint256,bytes32,address)", functions[0]->externalSignature());
+ }
+}
+
+BOOST_AUTO_TEST_CASE(function_external_types)
+{
+ ASTPointer<SourceUnit> sourceUnit;
+ char const* text = R"(
+ contract C {
+ uint a;
+ }
+ contract Test {
+ function boo(uint arg2, bool arg3, bytes8 arg4, bool[2] pairs, uint[] dynamic, C carg) external returns (uint ret) {
+ ret = 5;
+ }
+ })";
+ ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed");
+ for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
+ if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
+ {
+ auto functions = contract->getDefinedFunctions();
+ if (functions.empty())
+ continue;
+ BOOST_CHECK_EQUAL("boo(uint256,bool,bytes8,bool[2],uint256[],address)", functions[0]->externalSignature());
+ }
+}
+
+BOOST_AUTO_TEST_CASE(function_external_call_allowed_conversion)
+{
+ char const* text = R"(
+ contract C {}
+ contract Test {
+ function externalCall() {
+ C arg;
+ this.g(arg);
+ }
+ function g (C c) external {}
+ })";
+ BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
+}
+
+BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion)
+{
+ char const* text = R"(
+ contract C {}
+ contract Test {
+ function externalCall() {
+ address arg;
+ this.g(arg);
+ }
+ function g (C c) external {}
+ })";
+ BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion)
+{
+ char const* text = R"(
+ contract C {
+ uint a;
}
+ contract Test {
+ C a;
+ function g (C c) {}
+ function internalCall() {
+ g(a);
+ }
+ })";
+ BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
+}
+
+BOOST_AUTO_TEST_CASE(function_internal_not_allowed_conversion)
+{
+ char const* text = R"(
+ contract C {
+ uint a;
+ }
+ contract Test {
+ address a;
+ function g (C c) {}
+ function internalCall() {
+ g(a);
+ }
+ })";
+ BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(hash_collision_in_interface)