From c558aa06567f4e6e28b8f15c3dee73867fde447b Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 17 Apr 2015 16:17:21 +0200 Subject: [PATCH] Fixing detection of abstract contract --- AST.cpp | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/AST.cpp b/AST.cpp index 1c12ef5a1..5f681205d 100644 --- a/AST.cpp +++ b/AST.cpp @@ -155,45 +155,40 @@ void ContractDefinition::checkAbstractFunctions() void ContractDefinition::checkAbstractConstructors() { - set argumentsNeeded; - set argumentsProvided; + set argumentsNeeded; // check that we get arguments for all base constructors that need it. // If not mark the contract as abstract (not fully implemented) + vector const& bases = getLinearizedBaseContracts(); + for (ContractDefinition const* contract: bases) + if (FunctionDefinition const* constructor = contract->getConstructor()) + if (contract != this && !constructor->getParameters().empty()) + argumentsNeeded.insert(contract); + for (ContractDefinition const* contract: bases) { - FunctionDefinition const* constructor = contract->getConstructor(); - if (constructor) - { - if (!constructor->getParameters().empty()) - argumentsNeeded.insert(constructor); + if (FunctionDefinition const* constructor = contract->getConstructor()) for (auto const& modifier: constructor->getModifiers()) { auto baseContract = dynamic_cast( - modifier->getName()->getReferencedDeclaration()); + modifier->getName()->getReferencedDeclaration() + ); if (baseContract) - { - FunctionDefinition const* baseConstructor = baseContract->getConstructor(); - if (argumentsNeeded.count(baseConstructor) == 1) - argumentsProvided.insert(baseConstructor); - } + argumentsNeeded.erase(baseContract); } - } + for (ASTPointer const& base: contract->getBaseContracts()) { - ContractDefinition const* baseContract = dynamic_cast( - base->getName()->getReferencedDeclaration()); + auto baseContract = dynamic_cast( + base->getName()->getReferencedDeclaration() + ); solAssert(baseContract, ""); - FunctionDefinition const* baseConstructor = baseContract->getConstructor(); - if (argumentsNeeded.count(baseConstructor) == 1) - argumentsProvided.insert(baseConstructor); + if (!base->getArguments().empty()) + argumentsNeeded.erase(baseContract); } } - // add this contract's constructor to the provided too - if (getConstructor() && !getConstructor()->getParameters().empty()) - argumentsProvided.insert(getConstructor()); - if (argumentsProvided != argumentsNeeded) + if (!argumentsNeeded.empty()) setFullyImplemented(false); }