From 147e77b61fd202cbfd593270cc2639477ea7c61e Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 16 Dec 2014 23:45:24 +0100 Subject: [PATCH] Fix: Resolve function types of all contracts before checking types inside functions. --- CompilerStack.cpp | 9 +++++++++ NameAndTypeResolver.cpp | 13 +++++++------ NameAndTypeResolver.h | 2 ++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/CompilerStack.cpp b/CompilerStack.cpp index 23f5fd68f..1242c0aba 100644 --- a/CompilerStack.cpp +++ b/CompilerStack.cpp @@ -73,6 +73,15 @@ void CompilerStack::parse() resolver.resolveNamesAndTypes(*contract); m_contracts[contract->getName()].contract = contract; } + for (Source const* source: m_sourceOrder) + for (ASTPointer const& node: source->ast->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + { + m_globalContext->setCurrentContract(*contract); + resolver.updateDeclaration(*m_globalContext->getCurrentThis()); + resolver.checkTypeRequirements(*contract); + m_contracts[contract->getName()].contract = contract; + } m_parseSuccessful = true; } diff --git a/NameAndTypeResolver.cpp b/NameAndTypeResolver.cpp index 2ad276801..80732615c 100644 --- a/NameAndTypeResolver.cpp +++ b/NameAndTypeResolver.cpp @@ -49,8 +49,6 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) m_currentScope = &m_scopes[&_contract]; for (ASTPointer const& structDef: _contract.getDefinedStructs()) ReferencesResolver resolver(*structDef, *this, nullptr); - for (ASTPointer const& structDef: _contract.getDefinedStructs()) - structDef->checkValidityOfMembers(); for (ASTPointer const& variable: _contract.getStateVariables()) ReferencesResolver resolver(*variable, *this, nullptr); for (ASTPointer const& function: _contract.getDefinedFunctions()) @@ -59,13 +57,16 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) ReferencesResolver referencesResolver(*function, *this, function->getReturnParameterList().get()); } - // First, the parameter types of all functions need to be resolved before we can check - // the types, since it is possible to call functions that are only defined later - // in the source. - _contract.checkTypeRequirements(); m_currentScope = &m_scopes[nullptr]; } +void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract) +{ + for (ASTPointer const& structDef: _contract.getDefinedStructs()) + structDef->checkValidityOfMembers(); + _contract.checkTypeRequirements(); +} + void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) { m_scopes[nullptr].registerDeclaration(_declaration, true); diff --git a/NameAndTypeResolver.h b/NameAndTypeResolver.h index 1ff9febf0..23ac5fe77 100644 --- a/NameAndTypeResolver.h +++ b/NameAndTypeResolver.h @@ -46,6 +46,8 @@ public: void registerDeclarations(SourceUnit& _sourceUnit); /// Resolves all names and types referenced from the given contract. void resolveNamesAndTypes(ContractDefinition& _contract); + /// Check all type requirements in the given contract. + void checkTypeRequirements(ContractDefinition& _contract); /// Updates the given global declaration (used for "this"). Not to be used with declarations /// that create their own scope. void updateDeclaration(Declaration const& _declaration);