mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Prefer mobileType() to check rational range.
This commit is contained in:
parent
af354d7555
commit
80c368dac1
@ -772,12 +772,17 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
|||||||
{
|
{
|
||||||
// Infer type from value.
|
// Infer type from value.
|
||||||
solAssert(!var.typeName(), "");
|
solAssert(!var.typeName(), "");
|
||||||
if (
|
|
||||||
valueComponentType->category() == Type::Category::RationalNumber &&
|
|
||||||
!dynamic_pointer_cast<RationalNumberType const>(valueComponentType)->mobileType()
|
|
||||||
)
|
|
||||||
fatalTypeError(_statement.initialValue()->location(), "Invalid rational " + valueComponentType->toString() + ".");
|
|
||||||
var.annotation().type = valueComponentType->mobileType();
|
var.annotation().type = valueComponentType->mobileType();
|
||||||
|
if (!var.annotation().type)
|
||||||
|
if (valueComponentType->category() == Type::Category::RationalNumber)
|
||||||
|
fatalTypeError(
|
||||||
|
_statement.initialValue()->location(),
|
||||||
|
"Invalid rational " +
|
||||||
|
valueComponentType->toString() +
|
||||||
|
" (absolute value too large or divison by zero)."
|
||||||
|
);
|
||||||
|
else
|
||||||
|
solAssert(false, "");
|
||||||
var.accept(*this);
|
var.accept(*this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -787,8 +792,8 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
|||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
valueComponentType->category() == Type::Category::RationalNumber &&
|
valueComponentType->category() == Type::Category::RationalNumber &&
|
||||||
dynamic_pointer_cast<RationalNumberType const>(valueComponentType)->denominator() != 1 &&
|
dynamic_cast<RationalNumberType const&>(*valueComponentType).denominator() != 1 &&
|
||||||
!!valueComponentType->mobileType()
|
valueComponentType->mobileType()
|
||||||
)
|
)
|
||||||
typeError(
|
typeError(
|
||||||
_statement.location(),
|
_statement.location(),
|
||||||
@ -818,10 +823,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
|||||||
void TypeChecker::endVisit(ExpressionStatement const& _statement)
|
void TypeChecker::endVisit(ExpressionStatement const& _statement)
|
||||||
{
|
{
|
||||||
if (type(_statement.expression())->category() == Type::Category::RationalNumber)
|
if (type(_statement.expression())->category() == Type::Category::RationalNumber)
|
||||||
if (
|
if (!dynamic_cast<RationalNumberType const&>(*type(_statement.expression())).mobileType())
|
||||||
!dynamic_pointer_cast<RationalNumberType const>(type(_statement.expression()))->integerType() &&
|
|
||||||
!dynamic_pointer_cast<RationalNumberType const>(type(_statement.expression()))->fixedPointType()
|
|
||||||
)
|
|
||||||
typeError(_statement.expression().location(), "Invalid rational number.");
|
typeError(_statement.expression().location(), "Invalid rational number.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1128,8 +1130,8 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
|
|||||||
if (functionType->takesArbitraryParameters())
|
if (functionType->takesArbitraryParameters())
|
||||||
{
|
{
|
||||||
if (auto t = dynamic_cast<RationalNumberType const*>(argType.get()))
|
if (auto t = dynamic_cast<RationalNumberType const*>(argType.get()))
|
||||||
if (!t->integerType() && !t->fixedPointType())
|
if (!t->mobileType())
|
||||||
typeError(arguments[i]->location(), "Rational number too large.");
|
typeError(arguments[i]->location(), "Invalid rational number (too large or division by zero).");
|
||||||
}
|
}
|
||||||
else if (!type(*arguments[i])->isImplicitlyConvertibleTo(*parameterTypes[i]))
|
else if (!type(*arguments[i])->isImplicitlyConvertibleTo(*parameterTypes[i]))
|
||||||
typeError(
|
typeError(
|
||||||
@ -1367,7 +1369,7 @@ bool TypeChecker::visit(IndexAccess const& _access)
|
|||||||
solAssert(!numberType->denominator() != 1 ,"Invalid type for array access.");
|
solAssert(!numberType->denominator() != 1 ,"Invalid type for array access.");
|
||||||
if (!actualType.isDynamicallySized() && actualType.length() <= numberType->literalValue(nullptr))
|
if (!actualType.isDynamicallySized() && actualType.length() <= numberType->literalValue(nullptr))
|
||||||
typeError(_access.location(), "Out of bounds array access.");
|
typeError(_access.location(), "Out of bounds array access.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resultType = actualType.baseType();
|
resultType = actualType.baseType();
|
||||||
isLValue = actualType.location() != DataLocation::CallData;
|
isLValue = actualType.location() != DataLocation::CallData;
|
||||||
@ -1521,7 +1523,7 @@ void TypeChecker::expectType(Expression const& _expression, Type const& _expecte
|
|||||||
if (
|
if (
|
||||||
type(_expression)->category() == Type::Category::RationalNumber &&
|
type(_expression)->category() == Type::Category::RationalNumber &&
|
||||||
dynamic_pointer_cast<RationalNumberType const>(type(_expression))->denominator() != 1 &&
|
dynamic_pointer_cast<RationalNumberType const>(type(_expression))->denominator() != 1 &&
|
||||||
!!type(_expression)->mobileType()
|
type(_expression)->mobileType()
|
||||||
)
|
)
|
||||||
typeError(
|
typeError(
|
||||||
_expression.location(),
|
_expression.location(),
|
||||||
@ -1531,7 +1533,7 @@ void TypeChecker::expectType(Expression const& _expression, Type const& _expecte
|
|||||||
_expectedType.toString() +
|
_expectedType.toString() +
|
||||||
". Try converting to type " +
|
". Try converting to type " +
|
||||||
type(_expression)->mobileType()->toString() +
|
type(_expression)->mobileType()->toString() +
|
||||||
" or using an explicit conversion."
|
" or use an explicit conversion."
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
typeError(
|
typeError(
|
||||||
|
@ -766,20 +766,15 @@ u256 RationalNumberType::literalValue(Literal const*) const
|
|||||||
TypePointer RationalNumberType::mobileType() const
|
TypePointer RationalNumberType::mobileType() const
|
||||||
{
|
{
|
||||||
if (m_value.denominator() == 1)
|
if (m_value.denominator() == 1)
|
||||||
{
|
return integerType();
|
||||||
auto intType = integerType();
|
else
|
||||||
solAssert(!!intType, "mobileType called with invalid integer constant " + toString(false));
|
return fixedPointType();
|
||||||
return intType;
|
|
||||||
}
|
|
||||||
auto fixType = fixedPointType();
|
|
||||||
solAssert(!!fixType, "mobileType called with invalid fixed constant " + toString(false));
|
|
||||||
return fixType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: combine integerType() and fixedPointType() into one function
|
//TODO: combine integerType() and fixedPointType() into one function
|
||||||
shared_ptr<IntegerType const> RationalNumberType::integerType() const
|
shared_ptr<IntegerType const> RationalNumberType::integerType() const
|
||||||
{
|
{
|
||||||
solAssert(m_value.denominator() == 1, "Non integer type found.");
|
solAssert(m_value.denominator() == 1, "integerType() called for fractional number.");
|
||||||
bigint value = integerPart();
|
bigint value = integerPart();
|
||||||
bool negative = (value < 0);
|
bool negative = (value < 0);
|
||||||
if (negative) // convert to positive number of same bit requirements
|
if (negative) // convert to positive number of same bit requirements
|
||||||
|
@ -205,7 +205,7 @@ public:
|
|||||||
virtual unsigned sizeOnStack() const { return 1; }
|
virtual unsigned sizeOnStack() const { return 1; }
|
||||||
/// @returns the mobile (in contrast to static) type corresponding to the given type.
|
/// @returns the mobile (in contrast to static) type corresponding to the given type.
|
||||||
/// This returns the corresponding integer type for ConstantTypes and the pointer type
|
/// This returns the corresponding integer type for ConstantTypes and the pointer type
|
||||||
/// for storage reference types.
|
/// for storage reference types. Might return a null pointer if there is no fitting type.
|
||||||
virtual TypePointer mobileType() const { return shared_from_this(); }
|
virtual TypePointer mobileType() const { return shared_from_this(); }
|
||||||
/// @returns true if this is a non-value type and the data of this type is stored at the
|
/// @returns true if this is a non-value type and the data of this type is stored at the
|
||||||
/// given location.
|
/// given location.
|
||||||
|
Loading…
Reference in New Issue
Block a user