From 952bb6f01f55c3208417ac935f498af9523e2b9d Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 2 May 2018 12:32:23 +0200 Subject: [PATCH] Changes ContractCompiler::superContract into superContractRange, which also finds super contracts in the case of cross contract lookup. --- libsolidity/codegen/CompilerContext.cpp | 29 ++++++++++++++----------- libsolidity/codegen/CompilerContext.h | 10 +++++---- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index a35eea7387ce..6704f906e7f0 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -169,21 +169,20 @@ FunctionDefinition const& CompilerContext::resolveVirtualFunction(FunctionDefini if (scope->isLibrary()) return _function; solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); - return resolveVirtualFunction(_function, m_inheritanceHierarchy.begin()); + return resolveVirtualFunction(_function, {m_inheritanceHierarchy.begin(), m_inheritanceHierarchy.end()}); } FunctionDefinition const& CompilerContext::superFunction(FunctionDefinition const& _function, ContractDefinition const& _base) { solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); - return resolveVirtualFunction(_function, superContract(_base)); + return resolveVirtualFunction(_function, superContractRange(_base)); } FunctionDefinition const* CompilerContext::nextConstructor(ContractDefinition const& _contract) const { - vector::const_iterator it = superContract(_contract); - for (; it != m_inheritanceHierarchy.end(); ++it) - if ((*it)->constructor()) - return (*it)->constructor(); + for (auto const& base: superContractRange(_contract)) + if (base->constructor()) + return base->constructor(); return nullptr; } @@ -377,14 +376,13 @@ void CompilerContext::appendInlineAssembly( FunctionDefinition const& CompilerContext::resolveVirtualFunction( FunctionDefinition const& _function, - vector::const_iterator _searchStart + boost::iterator_range::const_iterator> _searchRange ) { string name = _function.name(); FunctionType functionType(_function); - auto it = _searchStart; - for (; it != m_inheritanceHierarchy.end(); ++it) - for (FunctionDefinition const* function: (*it)->definedFunctions()) + for (auto contract: _searchRange) + for (FunctionDefinition const* function: contract->definedFunctions()) if ( function->name() == name && !function->isConstructor() && @@ -395,12 +393,17 @@ FunctionDefinition const& CompilerContext::resolveVirtualFunction( return _function; // not reached } -vector::const_iterator CompilerContext::superContract(ContractDefinition const& _contract) const +boost::iterator_range::const_iterator> CompilerContext::superContractRange(ContractDefinition const &_contract) const { solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); auto it = find(m_inheritanceHierarchy.begin(), m_inheritanceHierarchy.end(), &_contract); - solAssert(it != m_inheritanceHierarchy.end(), "Base not found in inheritance hierarchy."); - return ++it; + if (it != m_inheritanceHierarchy.end()) + return {++it, m_inheritanceHierarchy.end()}; + + auto const& baseContracts = _contract.annotation().linearizedBaseContracts; + it = find(baseContracts.begin(), baseContracts.end(), &_contract); + solAssert(it != baseContracts.end(), "Base not found in base contracts."); + return {++it, baseContracts.end()}; } void CompilerContext::updateSourceLocation() diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 5776b5d1ba8e..1b549f129315 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -35,6 +35,8 @@ #include +#include + #include #include #include @@ -252,14 +254,14 @@ class CompilerContext }; private: - /// Searches the inheritance hierarchy towards the base starting from @a _searchStart and returns + /// Searches the inheritance hierarchy towards the base within @a _searchRange and returns /// the first function definition that is overwritten by _function. FunctionDefinition const& resolveVirtualFunction( FunctionDefinition const& _function, - std::vector::const_iterator _searchStart + boost::iterator_range::const_iterator> _searchRange ); - /// @returns an iterator to the contract directly above the given contract. - std::vector::const_iterator superContract(const ContractDefinition &_contract) const; + /// @returns an iterator range from the contract directly above the given contract to the end of the inheritance hierarchy. + boost::iterator_range::const_iterator> superContractRange(const ContractDefinition &_contract) const; /// Updates source location set in the assembly. void updateSourceLocation();