aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/ast
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-12-07 06:45:17 +0800
committerchriseth <c@ethdev.com>2016-12-12 18:12:12 +0800
commit273804503096d8d5d0c9d1fcece48da871f2d90f (patch)
tree7ba765f21be9a6f3177cb2a3023bc475e14f3a93 /libsolidity/ast
parent2df60bec923e1bac74cde00ae9bda641ca29d6c1 (diff)
downloaddexon-solidity-273804503096d8d5d0c9d1fcece48da871f2d90f.tar.gz
dexon-solidity-273804503096d8d5d0c9d1fcece48da871f2d90f.tar.zst
dexon-solidity-273804503096d8d5d0c9d1fcece48da871f2d90f.zip
Cleaner shift handling and type conversion for binary operations.
Diffstat (limited to 'libsolidity/ast')
-rw-r--r--libsolidity/ast/Types.cpp50
1 files changed, 20 insertions, 30 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 896d51fa..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)
{
@@ -342,24 +355,13 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe
return TypePointer();
if (Token::isShiftOp(_operator))
{
- // Disable >>> here.
- if (_operator == Token::SHR)
- return TypePointer();
-
// Shifts are not symmetric with respect to the type
if (isAddress())
return TypePointer();
- if (IntegerType const* otherInt = dynamic_cast<decltype(otherInt)>(_other.get()))
- {
- if (!otherInt->isAddress())
- return shared_from_this();
- }
- else if (RationalNumberType const* otherRat = dynamic_cast<decltype(otherRat)>(_other.get()))
- {
- if (!otherRat->isFractional())
- return shared_from_this();
- }
- 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
@@ -978,22 +980,10 @@ TypePointer FixedBytesType::binaryOperatorResult(Token::Value _operator, TypePoi
{
if (Token::isShiftOp(_operator))
{
- // Disable >>> here.
- if (_operator == Token::SHR)
+ if (isValidShiftAndAmountType(_operator, *_other))
+ return shared_from_this();
+ else
return TypePointer();
-
- // Shifts are not symmetric with respect to the type
- if (IntegerType const* otherInt = dynamic_cast<decltype(otherInt)>(_other.get()))
- {
- if (!otherInt->isAddress())
- return shared_from_this();
- }
- else if (RationalNumberType const* otherRat = dynamic_cast<decltype(otherRat)>(_other.get()))
- {
- if (!otherRat->isFractional())
- return shared_from_this();
- }
- return TypePointer();
}
auto commonType = dynamic_pointer_cast<FixedBytesType const>(Type::commonType(shared_from_this(), _other));