| 602 | } |
| 603 | |
| 604 | void TypeChecker::visitManually( |
| 605 | ModifierInvocation const& _modifier, |
| 606 | std::vector<ContractDefinition const*> const& _bases |
| 607 | ) |
| 608 | { |
| 609 | std::vector<ASTPointer<Expression>> const& arguments = |
| 610 | _modifier.arguments() ? *_modifier.arguments() : std::vector<ASTPointer<Expression>>(); |
| 611 | for (ASTPointer<Expression> const& argument: arguments) |
| 612 | argument->accept(*this); |
| 613 | |
| 614 | _modifier.name().accept(*this); |
| 615 | |
| 616 | auto const* declaration = &dereference(_modifier.name()); |
| 617 | std::vector<ASTPointer<VariableDeclaration>> emptyParameterList; |
| 618 | std::vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr; |
| 619 | if (auto modifierDecl = dynamic_cast<ModifierDefinition const*>(declaration)) |
| 620 | { |
| 621 | parameters = &modifierDecl->parameters(); |
| 622 | if (auto const* modifierContract = dynamic_cast<ContractDefinition const*>(modifierDecl->scope())) |
| 623 | if (m_currentContract) |
| 624 | { |
| 625 | if (!util::contains(m_currentContract->annotation().linearizedBaseContracts, modifierContract)) |
| 626 | m_errorReporter.typeError( |
| 627 | 9428_error, |
| 628 | _modifier.location(), |
| 629 | "Can only use modifiers defined in the current contract or in base contracts." |
| 630 | ); |
| 631 | } |
| 632 | if ( |
| 633 | *_modifier.name().annotation().requiredLookup == VirtualLookup::Static && |
| 634 | !modifierDecl->isImplemented() |
| 635 | ) |
| 636 | m_errorReporter.typeError( |
| 637 | 1835_error, |
| 638 | _modifier.location(), |
| 639 | "Cannot call unimplemented modifier. The modifier has no implementation in the referenced contract. Refer to it by its unqualified name if you want to call the implementation from the most derived contract." |
| 640 | ); |
| 641 | } |
| 642 | else |
| 643 | // check parameters for Base constructors |
| 644 | for (ContractDefinition const* base: _bases) |
| 645 | if (declaration == base) |
| 646 | { |
| 647 | if (auto referencedConstructor = base->constructor()) |
| 648 | parameters = &referencedConstructor->parameters(); |
| 649 | else |
| 650 | parameters = &emptyParameterList; |
| 651 | break; |
| 652 | } |
| 653 | if (!parameters) |
| 654 | { |
| 655 | m_errorReporter.typeError(4659_error, _modifier.location(), "Referenced declaration is neither modifier nor base class."); |
| 656 | return; |
| 657 | } |
| 658 | if (parameters->size() != arguments.size()) |
| 659 | { |
| 660 | m_errorReporter.typeError( |
| 661 | 2973_error, |
nothing calls this directly
no test coverage detected