diff options
author | Yoichi Hirai <i@yoichihirai.com> | 2016-12-14 23:31:28 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-14 23:31:27 +0800 |
commit | 18f8f29c0a3ed9404f2950c11d77f85d0117c6d5 (patch) | |
tree | 11fcb5408f609ab3e8f35d7e41fd7a42df0d1837 /libsolidity/ast | |
parent | e53d12557162275a135a4ae086ae05691bc23fa3 (diff) | |
parent | 08a11e309f241e602cc4754b6322e4bb0da57b17 (diff) | |
download | dexon-solidity-18f8f29c0a3ed9404f2950c11d77f85d0117c6d5.tar dexon-solidity-18f8f29c0a3ed9404f2950c11d77f85d0117c6d5.tar.gz dexon-solidity-18f8f29c0a3ed9404f2950c11d77f85d0117c6d5.tar.bz2 dexon-solidity-18f8f29c0a3ed9404f2950c11d77f85d0117c6d5.tar.lz dexon-solidity-18f8f29c0a3ed9404f2950c11d77f85d0117c6d5.tar.xz dexon-solidity-18f8f29c0a3ed9404f2950c11d77f85d0117c6d5.tar.zst dexon-solidity-18f8f29c0a3ed9404f2950c11d77f85d0117c6d5.zip |
Merge pull request #1487 from ethereum/shift-ops
Shift operators
Diffstat (limited to 'libsolidity/ast')
-rw-r--r-- | libsolidity/ast/Types.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index d9660bc0..03ff8471 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -251,6 +251,19 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition return members; } +bool isValidShiftAndAmountType(Token::Value _operator, Type const& _shiftAmountType) +{ + // Disable >>> here. + if (_operator == Token::SHR) + return false; + else if (IntegerType const* otherInt = dynamic_cast<decltype(otherInt)>(&_shiftAmountType)) + return !otherInt->isAddress(); + else if (RationalNumberType const* otherRat = dynamic_cast<decltype(otherRat)>(&_shiftAmountType)) + return otherRat->integerType() && !otherRat->integerType()->isSigned(); + else + return false; +} + IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier): m_bits(_bits), m_modifier(_modifier) { @@ -340,6 +353,17 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe _other->category() != category() ) return TypePointer(); + if (Token::isShiftOp(_operator)) + { + // Shifts are not symmetric with respect to the type + if (isAddress()) + return TypePointer(); + if (isValidShiftAndAmountType(_operator, *_other)) + return shared_from_this(); + else + return TypePointer(); + } + auto commonType = Type::commonType(shared_from_this(), _other); //might be a integer or fixed point if (!commonType) return TypePointer(); @@ -954,6 +978,14 @@ TypePointer FixedBytesType::unaryOperatorResult(Token::Value _operator) const TypePointer FixedBytesType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const { + if (Token::isShiftOp(_operator)) + { + if (isValidShiftAndAmountType(_operator, *_other)) + return shared_from_this(); + else + return TypePointer(); + } + auto commonType = dynamic_pointer_cast<FixedBytesType const>(Type::commonType(shared_from_this(), _other)); if (!commonType) return TypePointer(); |