aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/ast
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-12-06 01:40:50 +0800
committerchriseth <c@ethdev.com>2016-12-12 18:12:12 +0800
commit2df60bec923e1bac74cde00ae9bda641ca29d6c1 (patch)
treebc774c90fca8f0feca215ca498458a71f22e25c9 /libsolidity/ast
parentb8b4f5e9f9a89eac1218551b5da322b41c7813f4 (diff)
downloaddexon-solidity-2df60bec923e1bac74cde00ae9bda641ca29d6c1.tar.gz
dexon-solidity-2df60bec923e1bac74cde00ae9bda641ca29d6c1.tar.zst
dexon-solidity-2df60bec923e1bac74cde00ae9bda641ca29d6c1.zip
Type after shift should be type of left operand.
Diffstat (limited to 'libsolidity/ast')
-rw-r--r--libsolidity/ast/Types.cpp47
1 files changed, 42 insertions, 5 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 6b4dd432..896d51fa 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -340,6 +340,28 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe
_other->category() != category()
)
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();
+ }
+
auto commonType = Type::commonType(shared_from_this(), _other); //might be a integer or fixed point
if (!commonType)
return TypePointer();
@@ -347,11 +369,6 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe
// All integer types can be compared
if (Token::isCompareOp(_operator))
return commonType;
- // Disable >>> here.
- if (_operator == Token::SHR)
- return TypePointer();
- if (Token::isShiftOp(_operator) && !isAddress()) // && !_other->isAddress())
- return shared_from_this();
if (Token::isBooleanOp(_operator))
return TypePointer();
if (auto intType = dynamic_pointer_cast<IntegerType const>(commonType))
@@ -959,6 +976,26 @@ TypePointer FixedBytesType::unaryOperatorResult(Token::Value _operator) const
TypePointer FixedBytesType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
{
+ if (Token::isShiftOp(_operator))
+ {
+ // Disable >>> here.
+ if (_operator == Token::SHR)
+ 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));
if (!commonType)
return TypePointer();