diff options
author | Daniel Kirchner <daniel@ekpyron.org> | 2018-09-05 23:59:55 +0800 |
---|---|---|
committer | Daniel Kirchner <daniel@ekpyron.org> | 2018-09-13 21:15:49 +0800 |
commit | 12aaca16458861e9b622818d49a82c1a7026594e (patch) | |
tree | 7b51c4893c6646134618b6c20574317ec014f225 /libsolidity/ast | |
parent | 9214c7c34f5e4501a50cb29de964bbf04131f9a3 (diff) | |
download | dexon-solidity-12aaca16458861e9b622818d49a82c1a7026594e.tar dexon-solidity-12aaca16458861e9b622818d49a82c1a7026594e.tar.gz dexon-solidity-12aaca16458861e9b622818d49a82c1a7026594e.tar.bz2 dexon-solidity-12aaca16458861e9b622818d49a82c1a7026594e.tar.lz dexon-solidity-12aaca16458861e9b622818d49a82c1a7026594e.tar.xz dexon-solidity-12aaca16458861e9b622818d49a82c1a7026594e.tar.zst dexon-solidity-12aaca16458861e9b622818d49a82c1a7026594e.zip |
Add payable and non-payable state mutability to AddressType.
Diffstat (limited to 'libsolidity/ast')
-rw-r--r-- | libsolidity/ast/Types.cpp | 74 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 15 |
2 files changed, 74 insertions, 15 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index a302203b..25702f19 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -299,7 +299,7 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type) case Token::Byte: return make_shared<FixedBytesType>(1); case Token::Address: - return make_shared<AddressType>(); + return make_shared<AddressType>(StateMutability::NonPayable); case Token::Bool: return make_shared<BoolType>(); case Token::Bytes: @@ -340,6 +340,17 @@ TypePointer Type::fromElementaryTypeName(string const& _name) } return ref->copyForLocation(location, true); } + else if (t->category() == Type::Category::Address) + { + if (nameParts.size() == 2) + { + if (nameParts[1] == "payable") + return make_shared<AddressType>(StateMutability::Payable); + else + solAssert(false, "Invalid state mutability for address type: " + nameParts[1]); + } + return make_shared<AddressType>(StateMutability::NonPayable); + } else { solAssert(nameParts.size() == 1, "Storage location suffix only allowed for reference types"); @@ -439,21 +450,48 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition return members; } +AddressType::AddressType(StateMutability _stateMutability): + m_stateMutability(_stateMutability) +{ + solAssert(m_stateMutability == StateMutability::Payable || m_stateMutability == StateMutability::NonPayable, ""); +} + string AddressType::richIdentifier() const { - return "t_address"; + if (m_stateMutability == StateMutability::Payable) + return "t_address_payable"; + else + return "t_address"; +} + +bool AddressType::isImplicitlyConvertibleTo(Type const& _other) const +{ + if (_other.category() != category()) + return false; + AddressType const& other = dynamic_cast<AddressType const&>(_other); + + return other.m_stateMutability <= m_stateMutability; } bool AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const { + if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo)) + return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable(); return isImplicitlyConvertibleTo(_convertTo) || - _convertTo.category() == Category::Contract || _convertTo.category() == Category::Integer || (_convertTo.category() == Category::FixedBytes && 160 == dynamic_cast<FixedBytesType const&>(_convertTo).numBytes() * 8); } string AddressType::toString(bool) const { + if (m_stateMutability == StateMutability::Payable) + return "address payable"; + else + return "address"; +} + +string AddressType::canonicalName() const +{ return "address"; } @@ -479,17 +517,29 @@ TypePointer AddressType::binaryOperatorResult(Token::Value _operator, TypePointe return Type::commonType(shared_from_this(), _other); } +bool AddressType::operator==(Type const& _other) const +{ + if (_other.category() != category()) + return false; + AddressType const& other = dynamic_cast<AddressType const&>(_other); + return other.m_stateMutability == m_stateMutability; +} + MemberList::MemberMap AddressType::nativeMembers(ContractDefinition const*) const { - return { + MemberList::MemberMap members = { {"balance", make_shared<IntegerType>(256)}, {"call", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bool", "bytes memory"}, FunctionType::Kind::BareCall, false, StateMutability::Payable)}, {"callcode", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bool", "bytes memory"}, FunctionType::Kind::BareCallCode, false, StateMutability::Payable)}, {"delegatecall", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bool", "bytes memory"}, FunctionType::Kind::BareDelegateCall, false)}, - {"send", make_shared<FunctionType>(strings{"uint"}, strings{"bool"}, FunctionType::Kind::Send)}, - {"staticcall", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bool", "bytes memory"}, FunctionType::Kind::BareStaticCall, false, StateMutability::View)}, - {"transfer", make_shared<FunctionType>(strings{"uint"}, strings(), FunctionType::Kind::Transfer)} + {"staticcall", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bool", "bytes memory"}, FunctionType::Kind::BareStaticCall, false, StateMutability::View)} }; + if (m_stateMutability == StateMutability::Payable) + { + members.emplace_back(MemberList::Member{"send", make_shared<FunctionType>(strings{"uint"}, strings{"bool"}, FunctionType::Kind::Send)}); + members.emplace_back(MemberList::Member{"transfer", make_shared<FunctionType>(strings{"uint"}, strings(), FunctionType::Kind::Transfer)}); + } + return members; } namespace @@ -1476,7 +1526,9 @@ bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const bool ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const { - return isImplicitlyConvertibleTo(_convertTo) || _convertTo.category() == Category::Address; + if (auto const* addressType = dynamic_cast<AddressType const*>(&_convertTo)) + return isPayable() || (addressType->stateMutability() < StateMutability::Payable); + return isImplicitlyConvertibleTo(_convertTo); } bool ContractType::isPayable() const @@ -3275,7 +3327,7 @@ MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const { case Kind::Block: return MemberList::MemberMap({ - {"coinbase", make_shared<AddressType>()}, + {"coinbase", make_shared<AddressType>(StateMutability::Payable)}, {"timestamp", make_shared<IntegerType>(256)}, {"blockhash", make_shared<FunctionType>(strings{"uint"}, strings{"bytes32"}, FunctionType::Kind::BlockHash, false, StateMutability::View)}, {"difficulty", make_shared<IntegerType>(256)}, @@ -3284,7 +3336,7 @@ MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const }); case Kind::Message: return MemberList::MemberMap({ - {"sender", make_shared<AddressType>()}, + {"sender", make_shared<AddressType>(StateMutability::Payable)}, {"gas", make_shared<IntegerType>(256)}, {"value", make_shared<IntegerType>(256)}, {"data", make_shared<ArrayType>(DataLocation::CallData)}, @@ -3292,7 +3344,7 @@ MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const }); case Kind::Transaction: return MemberList::MemberMap({ - {"origin", make_shared<AddressType>()}, + {"origin", make_shared<AddressType>(StateMutability::Payable)}, {"gasprice", make_shared<IntegerType>(256)} }); case Kind::ABI: diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 7ee66838..a2d18b0a 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -321,15 +321,16 @@ class AddressType: public Type public: virtual Category category() const override { return Category::Address; } - explicit AddressType() - { - } + explicit AddressType(StateMutability _stateMutability); virtual std::string richIdentifier() const override; + virtual bool isImplicitlyConvertibleTo(Type const& _other) const override; virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override; + virtual bool operator==(Type const& _other) const override; + virtual unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : 160 / 8; } virtual unsigned storageBytes() const override { return 160 / 8; } virtual bool isValueType() const override { return true; } @@ -337,11 +338,17 @@ public: virtual MemberList::MemberMap nativeMembers(ContractDefinition const*) const override; virtual std::string toString(bool _short) const override; + virtual std::string canonicalName() const override; virtual u256 literalValue(Literal const* _literal) const override; virtual TypePointer encodingType() const override { return shared_from_this(); } virtual TypePointer interfaceType(bool) const override { return shared_from_this(); } + + StateMutability stateMutability(void) const { return m_stateMutability; } + +private: + StateMutability m_stateMutability; }; /** @@ -755,7 +762,7 @@ public: { if (isSuper()) return TypePointer{}; - return std::make_shared<AddressType>(); + return std::make_shared<AddressType>(isPayable() ? StateMutability::Payable : StateMutability::NonPayable); } virtual TypePointer interfaceType(bool _inLibrary) const override { |