Fix type inversion for shift and exp operators.

This commit is contained in:
chriseth
2020-06-03 13:46:26 +02:00
parent 894478ff8c
commit a6c773bd96
12 changed files with 66 additions and 10 deletions
+1
View File
@@ -96,6 +96,7 @@ public:
static IntegerType const* uint(unsigned _bits) { return integer(_bits, IntegerType::Modifier::Unsigned); }
static IntegerType const* uint256() { return uint(256); }
static IntegerType const* int256() { return integer(256, IntegerType::Modifier::Signed); }
static FixedPointType const* fixedPoint(unsigned m, unsigned n, FixedPointType::Modifier _modifier);
+32 -4
View File
@@ -967,10 +967,38 @@ TypeResult RationalNumberType::binaryOperatorResult(Token _operator, Type const*
{
if (_other->category() == Category::Integer || _other->category() == Category::FixedPoint)
{
auto commonType = Type::commonType(this, _other);
if (!commonType)
return nullptr;
return commonType->binaryOperatorResult(_operator, _other);
if (isFractional())
return TypeResult::err("Fractional literals not supported.");
else if (!integerType())
return TypeResult::err("Literal too large.");
// Shift and exp are not symmetric, so it does not make sense to swap
// the types as below. As an exception, we always use uint here.
if (TokenTraits::isShiftOp(_operator))
{
if (!isValidShiftAndAmountType(_operator, *_other))
return nullptr;
return isNegative() ? TypeProvider::int256() : TypeProvider::uint256();
}
else if (Token::Exp == _operator)
{
if (auto const* otherIntType = dynamic_cast<IntegerType const*>(_other))
{
if (otherIntType->isSigned())
return TypeResult::err("Exponentiation power is not allowed to be a signed integer type.");
}
else if (dynamic_cast<FixedPointType const*>(_other))
return TypeResult::err("Exponent is fractional.");
return isNegative() ? TypeProvider::int256() : TypeProvider::uint256();
}
else
{
auto commonType = Type::commonType(this, _other);
if (!commonType)
return nullptr;
return commonType->binaryOperatorResult(_operator, _other);
}
}
else if (_other->category() != category())
return nullptr;