aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2017-07-20 05:34:00 +0800
committerGitHub <noreply@github.com>2017-07-20 05:34:00 +0800
commit1dd4c7043bde70b0770ecdec036b8e8c949979e8 (patch)
tree667e1ab8943b068e6cfe961e1f0a9566a983aca4
parent6d6d4f69078a6417e1cfb89942f7df2264d89987 (diff)
parent72917c4f3513a73ae180767b854de8653be9a2f4 (diff)
downloaddexon-solidity-1dd4c7043bde70b0770ecdec036b8e8c949979e8.tar.gz
dexon-solidity-1dd4c7043bde70b0770ecdec036b8e8c949979e8.tar.zst
dexon-solidity-1dd4c7043bde70b0770ecdec036b8e8c949979e8.zip
Merge pull request #1544 from VoR0220/fixedPointTypeResolution
Fixed point type resolution
-rw-r--r--libsolidity/ast/Types.cpp101
-rw-r--r--libsolidity/ast/Types.h23
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp2
-rw-r--r--libsolidity/parsing/Token.cpp10
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp210
5 files changed, 164 insertions, 182 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 76bfb1a8..bcfccc3e 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -196,9 +196,9 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type)
case Token::UInt:
return make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned);
case Token::Fixed:
- return make_shared<FixedPointType>(128, 128, FixedPointType::Modifier::Signed);
+ return make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Signed);
case Token::UFixed:
- return make_shared<FixedPointType>(128, 128, FixedPointType::Modifier::Unsigned);
+ return make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Unsigned);
case Token::Byte:
return make_shared<FixedBytesType>(1);
case Token::Address:
@@ -352,12 +352,11 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
else if (_convertTo.category() == Category::FixedPoint)
{
FixedPointType const& convertTo = dynamic_cast<FixedPointType const&>(_convertTo);
- if (convertTo.integerBits() < m_bits || isAddress())
+
+ if (isAddress())
return false;
- else if (isSigned())
- return convertTo.isSigned();
else
- return !convertTo.isSigned() || convertTo.integerBits() > m_bits;
+ return maxValue() <= convertTo.maxIntegerValue() && minValue() >= convertTo.minIntegerValue();
}
else
return false;
@@ -487,22 +486,20 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons
return MemberList::MemberMap();
}
-FixedPointType::FixedPointType(int _integerBits, int _fractionalBits, FixedPointType::Modifier _modifier):
- m_integerBits(_integerBits), m_fractionalBits(_fractionalBits), m_modifier(_modifier)
+FixedPointType::FixedPointType(int _totalBits, int _fractionalDigits, FixedPointType::Modifier _modifier):
+ m_totalBits(_totalBits), m_fractionalDigits(_fractionalDigits), m_modifier(_modifier)
{
solAssert(
- m_integerBits + m_fractionalBits > 0 &&
- m_integerBits + m_fractionalBits <= 256 &&
- m_integerBits % 8 == 0 &&
- m_fractionalBits % 8 == 0,
+ 8 <= m_totalBits && m_totalBits <= 256 && m_totalBits % 8 == 0 &&
+ 0 <= m_fractionalDigits && m_fractionalDigits <= 80,
"Invalid bit number(s) for fixed type: " +
- dev::toString(_integerBits) + "x" + dev::toString(_fractionalBits)
- );
+ dev::toString(_totalBits) + "x" + dev::toString(_fractionalDigits)
+ );
}
string FixedPointType::identifier() const
{
- return "t_" + string(isSigned() ? "" : "u") + "fixed" + std::to_string(integerBits()) + "x" + std::to_string(fractionalBits());
+ return "t_" + string(isSigned() ? "" : "u") + "fixed" + std::to_string(m_totalBits) + "x" + std::to_string(m_fractionalDigits);
}
bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
@@ -510,12 +507,10 @@ bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
if (_convertTo.category() == category())
{
FixedPointType const& convertTo = dynamic_cast<FixedPointType const&>(_convertTo);
- if (convertTo.m_integerBits < m_integerBits || convertTo.m_fractionalBits < m_fractionalBits)
+ if (convertTo.numBits() < m_totalBits || convertTo.fractionalDigits() < m_fractionalDigits)
return false;
- else if (isSigned())
- return convertTo.isSigned();
else
- return !convertTo.isSigned() || (convertTo.m_integerBits > m_integerBits);
+ return convertTo.maxIntegerValue() >= maxIntegerValue() && convertTo.minIntegerValue() <= minIntegerValue();
}
return false;
}
@@ -549,13 +544,30 @@ bool FixedPointType::operator==(Type const& _other) const
if (_other.category() != category())
return false;
FixedPointType const& other = dynamic_cast<FixedPointType const&>(_other);
- return other.m_integerBits == m_integerBits && other.m_fractionalBits == m_fractionalBits && other.m_modifier == m_modifier;
+ return other.m_totalBits == m_totalBits && other.m_fractionalDigits == m_fractionalDigits && other.m_modifier == m_modifier;
}
string FixedPointType::toString(bool) const
{
string prefix = isSigned() ? "fixed" : "ufixed";
- return prefix + dev::toString(m_integerBits) + "x" + dev::toString(m_fractionalBits);
+ return prefix + dev::toString(m_totalBits) + "x" + dev::toString(m_fractionalDigits);
+}
+
+bigint FixedPointType::maxIntegerValue() const
+{
+ bigint maxValue = (bigint(1) << (m_totalBits - (isSigned() ? 1 : 0))) - 1;
+ return maxValue / pow(bigint(10), m_fractionalDigits);
+}
+
+bigint FixedPointType::minIntegerValue() const
+{
+ if (isSigned())
+ {
+ bigint minValue = -(bigint(1) << (m_totalBits - (isSigned() ? 1 : 0)));
+ return minValue / pow(bigint(10), m_fractionalDigits);
+ }
+ else
+ return bigint(0);
}
TypePointer FixedPointType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
@@ -743,13 +755,9 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
else if (_convertTo.category() == Category::FixedPoint)
{
if (auto fixed = fixedPointType())
- {
- // We disallow implicit conversion if we would have to truncate (fixedPointType()
- // can return a type that requires truncation).
- rational value = m_value * (bigint(1) << fixed->fractionalBits());
- return value.denominator() == 1 && fixed->isImplicitlyConvertibleTo(_convertTo);
- }
- return false;
+ return fixed->isImplicitlyConvertibleTo(_convertTo);
+ else
+ return false;
}
else if (_convertTo.category() == Category::FixedBytes)
{
@@ -953,10 +961,9 @@ u256 RationalNumberType::literalValue(Literal const*) const
else
{
auto fixed = fixedPointType();
- solAssert(!!fixed, "");
- rational shifted = m_value * (bigint(1) << fixed->fractionalBits());
- // truncate
- shiftedValue = shifted.numerator() / shifted.denominator();
+ solAssert(fixed, "");
+ int fractionalDigits = fixed->fractionalDigits();
+ shiftedValue = (m_value.numerator() / m_value.denominator()) * pow(bigint(10), fractionalDigits);
}
// we ignore the literal and hope that the type was correctly determined
@@ -997,22 +1004,21 @@ shared_ptr<IntegerType const> RationalNumberType::integerType() const
shared_ptr<FixedPointType const> RationalNumberType::fixedPointType() const
{
bool negative = (m_value < 0);
- unsigned fractionalBits = 0;
+ unsigned fractionalDigits = 0;
rational value = abs(m_value); // We care about the sign later.
rational maxValue = negative ?
rational(bigint(1) << 255, 1):
rational((bigint(1) << 256) - 1, 1);
- while (value * 0x100 <= maxValue && value.denominator() != 1 && fractionalBits < 256)
+ while (value * 10 <= maxValue && value.denominator() != 1 && fractionalDigits < 80)
{
- value *= 0x100;
- fractionalBits += 8;
+ value *= 10;
+ fractionalDigits++;
}
if (value > maxValue)
return shared_ptr<FixedPointType const>();
- // u256(v) is the actual value that will be put on the stack
- // From here on, very similar to integerType()
+ // This means we round towards zero for positive and negative values.
bigint v = value.numerator() / value.denominator();
if (negative)
// modify value to satisfy bit requirements for negative numbers:
@@ -1022,26 +1028,11 @@ shared_ptr<FixedPointType const> RationalNumberType::fixedPointType() const
if (v > u256(-1))
return shared_ptr<FixedPointType const>();
- unsigned totalBits = bytesRequired(v) * 8;
+ unsigned totalBits = max(bytesRequired(v), 1u) * 8;
solAssert(totalBits <= 256, "");
- unsigned integerBits = totalBits >= fractionalBits ? totalBits - fractionalBits : 0;
- // Special case: Numbers between -1 and 0 have their sign bit in the fractional part.
- if (negative && abs(m_value) < 1 && totalBits > fractionalBits)
- {
- fractionalBits += 8;
- integerBits = 0;
- }
-
- if (integerBits > 256 || fractionalBits > 256 || fractionalBits + integerBits > 256)
- return shared_ptr<FixedPointType const>();
- if (integerBits == 0 && fractionalBits == 0)
- {
- integerBits = 0;
- fractionalBits = 8;
- }
return make_shared<FixedPointType>(
- integerBits, fractionalBits,
+ totalBits, fractionalDigits,
negative ? FixedPointType::Modifier::Signed : FixedPointType::Modifier::Unsigned
);
}
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index c24cc11a..3d7dad16 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -342,7 +342,7 @@ public:
};
virtual Category category() const override { return Category::FixedPoint; }
- explicit FixedPointType(int _integerBits, int _fractionalBits, Modifier _modifier = Modifier::Unsigned);
+ explicit FixedPointType(int _totalBits, int _fractionalDigits, Modifier _modifier = Modifier::Unsigned);
virtual std::string identifier() const override;
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
@@ -352,8 +352,8 @@ public:
virtual bool operator==(Type const& _other) const override;
- virtual unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : (m_integerBits + m_fractionalBits) / 8; }
- virtual unsigned storageBytes() const override { return (m_integerBits + m_fractionalBits) / 8; }
+ virtual unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_totalBits / 8; }
+ virtual unsigned storageBytes() const override { return m_totalBits / 8; }
virtual bool isValueType() const override { return true; }
virtual std::string toString(bool _short) const override;
@@ -361,14 +361,21 @@ public:
virtual TypePointer encodingType() const override { return shared_from_this(); }
virtual TypePointer interfaceType(bool) const override { return shared_from_this(); }
- int numBits() const { return m_integerBits + m_fractionalBits; }
- int integerBits() const { return m_integerBits; }
- int fractionalBits() const { return m_fractionalBits; }
+ /// Number of bits used for this type in total.
+ int numBits() const { return m_totalBits; }
+ /// Number of decimal digits after the radix point.
+ int fractionalDigits() const { return m_fractionalDigits; }
bool isSigned() const { return m_modifier == Modifier::Signed; }
+ /// @returns the largest integer value this type con hold. Note that this is not the
+ /// largest value in general.
+ bigint maxIntegerValue() const;
+ /// @returns the smallest integer value this type can hold. Note hat this is not the
+ /// smallest value in general.
+ bigint minIntegerValue() const;
private:
- int m_integerBits;
- int m_fractionalBits;
+ int m_totalBits;
+ int m_fractionalDigits;
Modifier m_modifier;
};
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index 7067ddd5..782aad9d 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -504,7 +504,7 @@ void CompilerUtils::convertType(
//shift all integer bits onto the left side of the fixed type
FixedPointType const& targetFixedPointType = dynamic_cast<FixedPointType const&>(_targetType);
if (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack))
- if (targetFixedPointType.integerBits() > typeOnStack->numBits())
+ if (targetFixedPointType.numBits() > typeOnStack->numBits())
cleanHigherOrderBits(*typeOnStack);
solUnimplemented("Not yet implemented - FixedPointType.");
}
diff --git a/libsolidity/parsing/Token.cpp b/libsolidity/parsing/Token.cpp
index 66312f69..9cec0303 100644
--- a/libsolidity/parsing/Token.cpp
+++ b/libsolidity/parsing/Token.cpp
@@ -70,7 +70,7 @@ void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned con
else if (_baseType == Token::UFixedMxN || _baseType == Token::FixedMxN)
{
solAssert(
- _first + _second <= 256 && _first % 8 == 0 && _second % 8 == 0,
+ _first >= 8 && _first <= 256 && _first % 8 == 0 && _second <= 80,
"No elementary type " + string(Token::toString(_baseType)) + to_string(_first) + "x" + to_string(_second) + "."
);
}
@@ -157,12 +157,8 @@ tuple<Token::Value, unsigned int, unsigned int> Token::fromIdentifierOrKeyword(s
) {
int n = parseSize(positionX + 1, _literal.end());
if (
- 0 <= m && m <= 256 &&
- 8 <= n && n <= 256 &&
- m + n > 0 &&
- m + n <= 256 &&
- m % 8 == 0 &&
- n % 8 == 0
+ 8 <= m && m <= 256 && m % 8 == 0 &&
+ 0 <= n && n <= 80
) {
if (keyword == Token::UFixed)
return make_tuple(Token::UFixedMxN, m, n);
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 2a5613c0..4b29243a 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -2290,6 +2290,9 @@ BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName)
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 30, 0)) == *make_shared<FixedBytesType>(30));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 31, 0)) == *make_shared<FixedBytesType>(31));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 32, 0)) == *make_shared<FixedBytesType>(32));
+
+ BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Fixed, 0, 0)) == *make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Signed));
+ BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UFixed, 0, 0)) == *make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Unsigned));
}
BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1)
@@ -4033,7 +4036,7 @@ BOOST_AUTO_TEST_CASE(invalid_fixed_types_0x7_mxn)
fixed0x7 a = .3;
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, DeclarationError, "Identifier not found");
}
BOOST_AUTO_TEST_CASE(invalid_fixed_types_long_invalid_identifier)
@@ -4043,7 +4046,7 @@ BOOST_AUTO_TEST_CASE(invalid_fixed_types_long_invalid_identifier)
fixed99999999999999999999999999999999999999x7 b = 9.5;
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, DeclarationError, "Identifier not found");
}
BOOST_AUTO_TEST_CASE(invalid_fixed_types_7x8_mxn)
@@ -4053,7 +4056,7 @@ BOOST_AUTO_TEST_CASE(invalid_fixed_types_7x8_mxn)
fixed7x8 c = 3.12345678;
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, DeclarationError, "Identifier not found");
}
BOOST_AUTO_TEST_CASE(library_instances_cannot_be_used)
@@ -4067,7 +4070,7 @@ BOOST_AUTO_TEST_CASE(library_instances_cannot_be_used)
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "Member \"l\" not found or not visible after argument-dependent lookup in library L");
}
BOOST_AUTO_TEST_CASE(invalid_fixed_type_long)
@@ -4079,7 +4082,7 @@ BOOST_AUTO_TEST_CASE(invalid_fixed_type_long)
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, DeclarationError, "Identifier not found");
}
BOOST_AUTO_TEST_CASE(fixed_type_int_conversion)
@@ -4087,8 +4090,8 @@ BOOST_AUTO_TEST_CASE(fixed_type_int_conversion)
char const* text = R"(
contract test {
function f() {
- uint128 a = 3;
- int128 b = 4;
+ uint64 a = 3;
+ int64 b = 4;
fixed c = b;
ufixed d = a;
c; d;
@@ -4137,7 +4140,7 @@ BOOST_AUTO_TEST_CASE(invalid_int_implicit_conversion_from_fixed)
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "Type fixed128x19 is not implicitly convertible to expected type int256");
}
BOOST_AUTO_TEST_CASE(rational_unary_operation)
@@ -4145,10 +4148,9 @@ BOOST_AUTO_TEST_CASE(rational_unary_operation)
char const* text = R"(
contract test {
function f() {
- ufixed8x16 a = 3.25;
- fixed8x16 b = -3.25;
- a;
- b;
+ ufixed16x2 a = 3.25;
+ fixed16x2 b = -3.25;
+ a; b;
}
}
)";
@@ -4156,13 +4158,13 @@ BOOST_AUTO_TEST_CASE(rational_unary_operation)
text = R"(
contract test {
function f() {
- ufixed8x16 a = +3.25;
- fixed8x16 b = -3.25;
+ ufixed16x2 a = +3.25;
+ fixed16x2 b = -3.25;
a; b;
}
}
)";
- CHECK_WARNING(text,"Use of unary + is deprecated");
+ CHECK_WARNING(text, "Use of unary + is deprecated");
text = R"(
contract test {
function f(uint x) {
@@ -4179,10 +4181,10 @@ BOOST_AUTO_TEST_CASE(leading_zero_rationals_convert)
char const* text = R"(
contract A {
function f() {
- ufixed0x8 a = 0.5;
- ufixed0x56 b = 0.0000000000000006661338147750939242541790008544921875;
- fixed0x8 c = -0.5;
- fixed0x56 d = -0.0000000000000006661338147750939242541790008544921875;
+ ufixed16x2 a = 0.5;
+ ufixed256x52 b = 0.0000000000000006661338147750939242541790008544921875;
+ fixed16x2 c = -0.5;
+ fixed256x52 d = -0.0000000000000006661338147750939242541790008544921875;
a; b; c; d;
}
}
@@ -4195,12 +4197,12 @@ BOOST_AUTO_TEST_CASE(size_capabilities_of_fixed_point_types)
char const* text = R"(
contract test {
function f() {
- ufixed248x8 a = 123456781234567979695948382928485849359686494864095409282048094275023098123.5;
- ufixed0x256 b = 0.920890746623327805482905058466021565416131529487595827354393978494366605267637829135688384325135165352082715782143655824815685807141335814463015972119819459298455224338812271036061391763384038070334798471324635050876128428143374549108557403087615966796875;
- ufixed0x256 c = 0.0000000000015198847363997979984922685411315294875958273543939784943666052676464653042434787697605517039455161817147718251801220885263595179331845639229818863564267318422845592626219390573301877339317935702714669975697814319204326238832436501979827880859375;
- fixed248x8 d = -123456781234567979695948382928485849359686494864095409282048094275023098123.5;
- fixed0x256 e = -0.93322335481643744342575580035176794825198893968114429702091846411734101080123092162893656820177312738451291806995868682861328125;
- fixed0x256 g = -0.00011788606643744342575580035176794825198893968114429702091846411734101080123092162893656820177312738451291806995868682861328125;
+ ufixed256x1 a = 123456781234567979695948382928485849359686494864095409282048094275023098123.5;
+ ufixed256x77 b = 0.920890746623327805482905058466021565416131529487595827354393978494366605267637;
+ ufixed224x78 c = 0.000000000001519884736399797998492268541131529487595827354393978494366605267646;
+ fixed256x1 d = -123456781234567979695948382928485849359686494864095409282048094275023098123.5;
+ fixed256x76 e = -0.93322335481643744342575580035176794825198893968114429702091846411734101080123;
+ fixed256x79 g = -0.0001178860664374434257558003517679482519889396811442970209184641173410108012309;
a; b; c; d; e; g;
}
}
@@ -4208,17 +4210,30 @@ BOOST_AUTO_TEST_CASE(size_capabilities_of_fixed_point_types)
CHECK_SUCCESS(text);
}
+BOOST_AUTO_TEST_CASE(zero_handling)
+{
+ char const* text = R"(
+ contract test {
+ function f() {
+ fixed16x2 a = 0; a;
+ ufixed32x1 b = 0; b;
+ }
+ }
+ )";
+ CHECK_SUCCESS(text);
+}
+
BOOST_AUTO_TEST_CASE(fixed_type_invalid_implicit_conversion_size)
{
char const* text = R"(
contract test {
function f() {
ufixed a = 11/4;
- ufixed248x8 b = a;
+ ufixed248x8 b = a; b;
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "Type ufixed128x19 is not implicitly convertible to expected type ufixed248x8");
}
BOOST_AUTO_TEST_CASE(fixed_type_invalid_implicit_conversion_lost_data)
@@ -4226,11 +4241,11 @@ BOOST_AUTO_TEST_CASE(fixed_type_invalid_implicit_conversion_lost_data)
char const* text = R"(
contract test {
function f() {
- ufixed0x256 a = 1/3;
+ ufixed256x1 a = 1/3; a;
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "is not implicitly convertible to expected type ufixed256x1");
}
BOOST_AUTO_TEST_CASE(fixed_type_valid_explicit_conversions)
@@ -4238,10 +4253,9 @@ BOOST_AUTO_TEST_CASE(fixed_type_valid_explicit_conversions)
char const* text = R"(
contract test {
function f() {
- ufixed0x256 a = ufixed0x256(1/3);
- ufixed0x248 b = ufixed0x248(1/3);
- ufixed0x8 c = ufixed0x8(1/3);
- a; b; c;
+ ufixed256x80 a = ufixed256x80(1/3); a;
+ ufixed248x80 b = ufixed248x80(1/3); b;
+ ufixed8x1 c = ufixed8x1(1/3); c;
}
}
)";
@@ -4253,23 +4267,35 @@ BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_rational)
char const* text = R"(
contract test {
function f() {
- uint[3.5] a;
+ uint[3.5] a; a;
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal");
}
-BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_fixed_type)
+BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_signed_fixed_type)
{
char const* text = R"(
contract test {
function f() {
- uint[fixed(3.5)] a;
+ uint[fixed(3.5)] a; a;
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_unsigned_fixed_type)
+{
+ char const* text = R"(
+ contract test {
+ function f() {
+ uint[ufixed(3.5)] a; a;
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal");
}
BOOST_AUTO_TEST_CASE(rational_to_bytes_implicit_conversion)
@@ -4277,11 +4303,11 @@ BOOST_AUTO_TEST_CASE(rational_to_bytes_implicit_conversion)
char const* text = R"(
contract test {
function f() {
- bytes32 c = 3.2;
+ bytes32 c = 3.2; c;
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "is not implicitly convertible to expected type bytes32");
}
BOOST_AUTO_TEST_CASE(fixed_to_bytes_implicit_conversion)
@@ -4290,18 +4316,18 @@ BOOST_AUTO_TEST_CASE(fixed_to_bytes_implicit_conversion)
contract test {
function f() {
fixed a = 3.25;
- bytes32 c = a;
+ bytes32 c = a; c;
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "fixed128x19 is not implicitly convertible to expected type bytes32");
}
BOOST_AUTO_TEST_CASE(mapping_with_fixed_literal)
{
char const* text = R"(
contract test {
- mapping(ufixed8x248 => string) fixedString;
+ mapping(ufixed8x1 => string) fixedString;
function f() {
fixedString[0.5] = "Half";
}
@@ -4341,7 +4367,7 @@ BOOST_AUTO_TEST_CASE(inline_array_rationals)
char const* text = R"(
contract test {
function f() {
- ufixed8x8[4] memory a = [3.5, 4.125, 2.5, 4.0];
+ ufixed128x3[4] memory a = [ufixed128x3(3.5), 4.125, 2.5, 4.0];
}
}
)";
@@ -4358,7 +4384,7 @@ BOOST_AUTO_TEST_CASE(rational_index_access)
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "rational_const 1/2 is not implicitly convertible to expected type uint256");
}
BOOST_AUTO_TEST_CASE(rational_to_fixed_literal_expression)
@@ -4366,12 +4392,12 @@ BOOST_AUTO_TEST_CASE(rational_to_fixed_literal_expression)
char const* text = R"(
contract test {
function f() {
- ufixed8x8 a = 3.5 * 3;
- ufixed8x8 b = 4 - 2.5;
- ufixed8x8 c = 11 / 4;
- ufixed16x240 d = 599 + 0.21875;
- ufixed8x248 e = ufixed8x248(35.245 % 12.9);
- ufixed8x248 f = ufixed8x248(1.2 % 2);
+ ufixed64x8 a = 3.5 * 3;
+ ufixed64x8 b = 4 - 2.5;
+ ufixed64x8 c = 11 / 4;
+ ufixed240x5 d = 599 + 0.21875;
+ ufixed256x80 e = ufixed256x80(35.245 % 12.9);
+ ufixed256x80 f = ufixed256x80(1.2 % 2);
fixed g = 2 ** -2;
a; b; c; d; e; f; g;
}
@@ -4380,7 +4406,7 @@ BOOST_AUTO_TEST_CASE(rational_to_fixed_literal_expression)
CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(rational_as_exponent_value_neg_decimal)
+BOOST_AUTO_TEST_CASE(rational_as_exponent_value_signed)
{
char const* text = R"(
contract test {
@@ -4389,10 +4415,10 @@ BOOST_AUTO_TEST_CASE(rational_as_exponent_value_neg_decimal)
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "not compatible with types");
}
-BOOST_AUTO_TEST_CASE(rational_as_exponent_value_pos_decimal)
+BOOST_AUTO_TEST_CASE(rational_as_exponent_value_unsigned)
{
char const* text = R"(
contract test {
@@ -4401,7 +4427,7 @@ BOOST_AUTO_TEST_CASE(rational_as_exponent_value_pos_decimal)
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "not compatible with types");
}
BOOST_AUTO_TEST_CASE(rational_as_exponent_half)
@@ -4409,11 +4435,11 @@ BOOST_AUTO_TEST_CASE(rational_as_exponent_half)
char const* text = R"(
contract test {
function f() {
- ufixed24x24 b = 2 ** (1/2);
+ 2 ** (1/2);
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "not compatible with types");
}
BOOST_AUTO_TEST_CASE(rational_as_exponent_value_neg_quarter)
@@ -4421,11 +4447,11 @@ BOOST_AUTO_TEST_CASE(rational_as_exponent_value_neg_quarter)
char const* text = R"(
contract test {
function f() {
- fixed40x40 c = 42 ** (-1/4);
+ 42 ** (-1/4);
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "not compatible with types");
}
BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_15)
@@ -4433,23 +4459,11 @@ BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_15)
char const* text = R"(
contract test {
function f() {
- ufixed a = 3 ** ufixed(1.5);
- }
- }
- )";
- BOOST_CHECK(!success(text));
-}
-
-BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_half)
-{
- char const* text = R"(
- contract test {
- function f() {
- ufixed b = 2 ** ufixed(1/2);
+ var a = 3 ** ufixed(1.5);
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "not compatible with types");
}
BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_neg)
@@ -4457,23 +4471,11 @@ BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_neg)
char const* text = R"(
contract test {
function f() {
- fixed c = 42 ** fixed(-1/4);
- }
- }
- )";
- BOOST_CHECK(!success(text));
-}
-
-BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_neg_decimal)
-{
- char const* text = R"(
- contract test {
- function f() {
- fixed d = 16 ** fixed(-0.5);
+ var c = 42 ** fixed(-1/4);
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "not compatible with types");
}
BOOST_AUTO_TEST_CASE(var_capable_of_holding_constant_rationals)
@@ -4521,11 +4523,11 @@ BOOST_AUTO_TEST_CASE(rational_bitnot_unary_operation)
char const* text = R"(
contract test {
function f() {
- fixed a = ~3.5;
+ ~fixed(3.5);
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "cannot be applied");
}
BOOST_AUTO_TEST_CASE(rational_bitor_binary_operation)
@@ -4533,11 +4535,11 @@ BOOST_AUTO_TEST_CASE(rational_bitor_binary_operation)
char const* text = R"(
contract test {
function f() {
- fixed a = 1.5 | 3;
+ fixed(1.5) | 3;
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "not compatible with types");
}
BOOST_AUTO_TEST_CASE(rational_bitxor_binary_operation)
@@ -4545,11 +4547,11 @@ BOOST_AUTO_TEST_CASE(rational_bitxor_binary_operation)
char const* text = R"(
contract test {
function f() {
- fixed a = 1.75 ^ 3;
+ fixed(1.75) ^ 3;
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "not compatible with types");
}
BOOST_AUTO_TEST_CASE(rational_bitand_binary_operation)
@@ -4557,25 +4559,11 @@ BOOST_AUTO_TEST_CASE(rational_bitand_binary_operation)
char const* text = R"(
contract test {
function f() {
- fixed a = 1.75 & 3;
- }
- }
- )";
- BOOST_CHECK(!success(text));
-}
-
-BOOST_AUTO_TEST_CASE(zero_handling)
-{
- char const* text = R"(
- contract test {
- function f() {
- fixed8x8 a = 0;
- ufixed8x8 b = 0;
- a; b;
+ fixed(1.75) & 3;
}
}
)";
- CHECK_SUCCESS(text);
+ CHECK_ERROR(text, TypeError, "not compatible with types");
}
BOOST_AUTO_TEST_CASE(missing_bool_conversion)
@@ -4595,7 +4583,7 @@ BOOST_AUTO_TEST_CASE(integer_and_fixed_interaction)
char const* text = R"(
contract test {
function f() {
- ufixed a = uint128(1) + ufixed(2);
+ ufixed a = uint64(1) + ufixed(2);
}
}
)";
@@ -4625,7 +4613,7 @@ BOOST_AUTO_TEST_CASE(one_divided_by_three_integer_conversion)
}
}
)";
- BOOST_CHECK(!success(text));
+ CHECK_ERROR(text, TypeError, "is not implicitly convertible to expected type uint256. Try converting to type ufixed256x77");
}
BOOST_AUTO_TEST_CASE(unused_return_value)