diff options
author | chriseth <c@ethdev.com> | 2015-11-28 05:24:00 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-11-29 07:16:07 +0800 |
commit | f9e52c9db1ef23000f5721a462aba3fa8d681749 (patch) | |
tree | d1b77769961618d027c794131949efe021fa4b49 /libsolidity | |
parent | 93b3237c6ae526d3ff5aa0d23d48319cf705baee (diff) | |
download | dexon-solidity-f9e52c9db1ef23000f5721a462aba3fa8d681749.tar.gz dexon-solidity-f9e52c9db1ef23000f5721a462aba3fa8d681749.tar.zst dexon-solidity-f9e52c9db1ef23000f5721a462aba3fa8d681749.zip |
Also check the object type for bound functions.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 11 | ||||
-rw-r--r-- | libsolidity/ast/AST_accept.h | 12 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 5 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 4 |
4 files changed, 23 insertions, 9 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 22fb1e96..851266bd 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1128,7 +1128,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) for (auto it = possibleMembers.begin(); it != possibleMembers.end();) if ( it->type->category() == Type::Category::Function && - !dynamic_cast<FunctionType const&>(*it->type).canTakeArguments(*argumentTypes) + !dynamic_cast<FunctionType const&>(*it->type).canTakeArguments(*argumentTypes, exprType) ) it = possibleMembers.erase(it); else @@ -1163,6 +1163,15 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) auto& annotation = _memberAccess.annotation(); annotation.referencedDeclaration = possibleMembers.front().declaration; annotation.type = possibleMembers.front().type; + + if (auto funType = dynamic_cast<FunctionType const*>(annotation.type.get())) + if (funType->bound() && !exprType->isImplicitlyConvertibleTo(*funType->selfType())) + typeError( + _memberAccess.location(), + "Function \"" + memberName + "\" cannot be called on an object of type " + + exprType->toString() + " (expected " + funType->selfType()->toString() + ")" + ); + if (exprType->category() == Type::Category::Struct) annotation.isLValue = true; else if (exprType->category() == Type::Category::Array) diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index 3f7b8d36..61370c55 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -127,9 +127,9 @@ void UsingForDirective::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) { - if (m_libraryName) - m_libraryName->accept(_visitor); - m_typeName->accept(_visitor); + m_libraryName->accept(_visitor); + if (m_typeName) + m_typeName->accept(_visitor); } _visitor.endVisit(*this); } @@ -138,9 +138,9 @@ void UsingForDirective::accept(ASTConstVisitor& _visitor) const { if (_visitor.visit(*this)) { - if (m_libraryName) - m_libraryName->accept(_visitor); - m_typeName->accept(_visitor); + m_libraryName->accept(_visitor); + if (m_typeName) + m_typeName->accept(_visitor); } _visitor.endVisit(*this); } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 44586a6d..0409ac63 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1640,8 +1640,11 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con } } -bool FunctionType::canTakeArguments(TypePointers const& _argumentTypes) const +bool FunctionType::canTakeArguments(TypePointers const& _argumentTypes, TypePointer const& _selfType) const { + solAssert(!bound() || _selfType, ""); + if (bound() && !_selfType->isImplicitlyConvertibleTo(*selfType())) + return false; TypePointers paramTypes = parameterTypes(); if (takesArbitraryParameters()) return true; diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 0f74f599..9224f292 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -829,7 +829,9 @@ public: /// @returns true if this function can take the given argument types (possibly /// after implicit conversion). - bool canTakeArguments(TypePointers const& _arguments) const; + /// @param _selfType if the function is bound, this has to be supplied and is the type of the + /// expression the function is called on. + bool canTakeArguments(TypePointers const& _arguments, TypePointer const& _selfType = TypePointer()) const; /// @returns true if the types of parameters are equal (does't check return parameter types) bool hasEqualArgumentTypes(FunctionType const& _other) const; |