From beba2705ba2fd9f87bf76f439c4a99cec0f6a06d Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 2 Apr 2015 16:56:12 +0200 Subject: Check all constructors in inheritance chain get args - Also add a missing override in a function of EnumValue --- AST.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'AST.cpp') diff --git a/AST.cpp b/AST.cpp index 37016646..4d183889 100644 --- a/AST.cpp +++ b/AST.cpp @@ -54,6 +54,7 @@ void ContractDefinition::checkTypeRequirements() checkIllegalOverrides(); checkAbstractFunctions(); + checkAbstractConstructors(); FunctionDefinition const* constructor = getConstructor(); if (constructor && !constructor->getReturnParameters().empty()) @@ -152,6 +153,47 @@ void ContractDefinition::checkAbstractFunctions() } } +void ContractDefinition::checkAbstractConstructors() +{ + set argumentsNeeded; + set argumentsProvided; + // 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) + { + FunctionDefinition const* constructor = contract->getConstructor(); + if (constructor) + { + if (!constructor->getParameters().empty()) + argumentsProvided.insert(constructor); + for (auto const& modifier: constructor->getModifiers()) + { + auto baseContract = dynamic_cast( + modifier->getName()->getReferencedDeclaration()); + if (baseContract) + { + FunctionDefinition const* baseConstructor = baseContract->getConstructor(); + if (argumentsProvided.count(baseConstructor) == 1) + argumentsNeeded.insert(baseConstructor); + } + } + } + + for (ASTPointer const& base: contract->getBaseContracts()) + { + ContractDefinition const* baseContract = dynamic_cast( + base->getName()->getReferencedDeclaration()); + solAssert(baseContract, ""); + FunctionDefinition const* baseConstructor = baseContract->getConstructor(); + if (argumentsProvided.count(baseConstructor) == 1) + argumentsNeeded.insert(baseConstructor); + } + } + if (argumentsProvided != argumentsNeeded) + setFullyImplemented(false); +} + void ContractDefinition::checkIllegalOverrides() const { // TODO unify this at a later point. for this we need to put the constness and the access specifier -- cgit