diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 763c34f21..00f91774d 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -328,8 +328,6 @@ void TypeChecker::endVisit(ModifierDefinition const& _modifier) bool TypeChecker::visit(FunctionDefinition const& _function) { - bool isLibraryFunction = _function.inContractKind() == ContractKind::Library; - if (_function.markedVirtual()) { if (_function.annotation().contract->isInterface()) @@ -340,7 +338,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) if (_function.isPayable()) { - if (isLibraryFunction) + if (_function.libraryFunction()) m_errorReporter.typeError(7708_error, _function.location(), "Library functions cannot be payable."); if (_function.isOrdinary() && !_function.isPartOfExternalInterface()) m_errorReporter.typeError(5587_error, _function.location(), "Internal functions cannot be payable."); @@ -350,15 +348,13 @@ bool TypeChecker::visit(FunctionDefinition const& _function) { if (var.referenceLocation() != VariableDeclaration::Location::Storage) { - if (!isLibraryFunction && _function.isPublic()) + if (!_function.libraryFunction() && _function.isPublic()) m_errorReporter.typeError(3442_error, var.location(), "Mapping types can only have a data location of \"storage\" and thus only be parameters or return variables for internal or library functions."); else m_errorReporter.typeError(5380_error, var.location(), "Mapping types can only have a data location of \"storage\"." ); } else - { - solAssert(isLibraryFunction || !_function.isPublic(), "Mapping types for parameters or return variables can only be used in internal or library functions."); - } + solAssert(_function.libraryFunction() || !_function.isPublic(), "Mapping types for parameters or return variables can only be used in internal or library functions."); } else { @@ -366,7 +362,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) m_errorReporter.typeError(3312_error, var.location(), "Type is required to live outside storage."); if (_function.isPublic()) { - auto iType = type(var)->interfaceType(isLibraryFunction); + auto iType = type(var)->interfaceType(_function.libraryFunction()); if (!iType) { @@ -378,7 +374,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) if ( _function.isPublic() && !_function.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2) && - !typeSupportedByOldABIEncoder(*type(var), isLibraryFunction) + !typeSupportedByOldABIEncoder(*type(var), _function.libraryFunction()) ) m_errorReporter.typeError( 4957_error, @@ -435,7 +431,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) _function.body().accept(*this); else if (_function.isConstructor()) m_errorReporter.typeError(5700_error, _function.location(), "Constructor must be implemented if declared."); - else if (isLibraryFunction) + else if (_function.libraryFunction()) m_errorReporter.typeError(9231_error, _function.location(), "Library functions must be implemented if declared."); else if (!_function.virtualSemantics()) m_errorReporter.typeError(5424_error, _function.location(), "Functions without implementation must be marked virtual."); @@ -1830,7 +1826,7 @@ void TypeChecker::typeCheckFallbackFunction(FunctionDefinition const& _function) { solAssert(_function.isFallback(), ""); - if (_function.inContractKind() == ContractKind::Library) + if (_function.libraryFunction()) m_errorReporter.typeError(5982_error, _function.location(), "Libraries cannot have fallback functions."); if (_function.stateMutability() != StateMutability::NonPayable && _function.stateMutability() != StateMutability::Payable) m_errorReporter.typeError( @@ -1857,7 +1853,7 @@ void TypeChecker::typeCheckReceiveFunction(FunctionDefinition const& _function) { solAssert(_function.isReceive(), ""); - if (_function.inContractKind() == ContractKind::Library) + if (_function.libraryFunction()) m_errorReporter.typeError(4549_error, _function.location(), "Libraries cannot have receive ether functions."); if (_function.stateMutability() != StateMutability::Payable) diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 230e0a8ba..09c8a34b3 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -276,7 +276,7 @@ void ViewPureChecker::reportMutability( { // We do not warn for library functions because they cannot be payable anyway. // Also internal functions should be allowed to use `msg.value`. - if (m_currentFunction->isPublic() && m_currentFunction->inContractKind() != ContractKind::Library) + if (m_currentFunction->isPublic() && !m_currentFunction->libraryFunction()) { if (_nestedLocation) m_errorReporter.typeError( diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 3edb08476..c11a05a02 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -287,11 +287,11 @@ TypeDeclarationAnnotation& EnumDefinition::annotation() const return initAnnotation(); } -ContractKind FunctionDefinition::inContractKind() const +bool FunctionDefinition::libraryFunction() const { - auto contractDef = dynamic_cast(scope()); - solAssert(contractDef, "Enclosing Scope of FunctionDefinition was not set."); - return contractDef->contractKind(); + if (auto const* contractDef = dynamic_cast(scope())) + return contractDef->isLibrary(); + return false; } FunctionTypePointer FunctionDefinition::functionType(bool _internal) const diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 721e76791..c1c02b2bb 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -799,6 +799,7 @@ public: void accept(ASTConstVisitor& _visitor) const override; StateMutability stateMutability() const { return m_stateMutability; } + bool libraryFunction() const; bool isOrdinary() const { return m_kind == Token::Function; } bool isConstructor() const { return m_kind == Token::Constructor; } bool isFallback() const { return m_kind == Token::Fallback; } @@ -825,8 +826,6 @@ public: /// @returns the external identifier of this function (the hash of the signature) as a hex string. std::string externalIdentifierHex() const; - ContractKind inContractKind() const; - TypePointer type() const override; TypePointer typeViaContractName() const override;