From a7732d201326ea569422da704570a708dbffa2d1 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Mon, 1 Jun 2015 22:00:27 +0200 Subject: [PATCH 1/5] test Conflicts: test/libsolidity/SolidityEndToEndTest.cpp --- test/libsolidity/SolidityEndToEndTest.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 9f6f27d7d..e7287b399 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -4172,6 +4172,17 @@ BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund) BOOST_CHECK(compileAndRunWthoutCheck(sourceCode, 0, "A").empty()); } +BOOST_AUTO_TEST_CASE(positive_integers_to_signed) +{ + char const* sourceCode = R"( + contract test { + int8 public x = 2; + } + )"; + compileAndRun(sourceCode, 0, "test"); + BOOST_CHECK(callContractFunction("x()") == encodeArgs(2)); +} + BOOST_AUTO_TEST_SUITE_END() } From 4757651b6453bac1057a2c7c970e1475a70678be Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Wed, 3 Jun 2015 16:14:23 +0200 Subject: [PATCH 2/5] - conversion of positive literals to signed int - tests --- libsolidity/AST.cpp | 12 ++++-- libsolidity/Types.cpp | 36 +++++++++++------ test/libsolidity/SolidityEndToEndTest.cpp | 4 ++ .../SolidityNameAndTypeResolution.cpp | 40 +++++++++++++++++++ 4 files changed, 77 insertions(+), 15 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 248abfdb9..a209235dc 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -686,9 +686,15 @@ void Expression::expectType(Type const& _expectedType) checkTypeRequirements(nullptr); Type const& type = *getType(); if (!type.isImplicitlyConvertibleTo(_expectedType)) - BOOST_THROW_EXCEPTION(createTypeError("Type " + type.toString() + - " not implicitly convertible to expected type " - + _expectedType.toString() + ".")); + BOOST_THROW_EXCEPTION( + createTypeError( + "Type " + + type.toString() + + " is not implicitly convertible to expected type " + + _expectedType.toString() + + "." + ) + ); } void Expression::requireLValue() diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 0e9ea9876..c4238f773 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -361,17 +361,28 @@ IntegerConstantType::IntegerConstantType(Literal const& _literal) bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) const { - shared_ptr integerType = getIntegerType(); - if (!integerType) - return false; - - if (_convertTo.getCategory() == Category::FixedBytes) + if (IntegerType const* integerType = dynamic_cast(&_convertTo)) { - FixedBytesType const& convertTo = dynamic_cast(_convertTo); - return convertTo.getNumBytes() * 8 >= integerType->getNumBits(); + if (m_value == 0) + return true; + int forSignBit = (integerType->isSigned() ? 1 : 0); + if (m_value > 0) + { + if (m_value <= (u256(-1) >> (256 - integerType->getNumBits() + forSignBit))) + return true; + } + else if (-m_value <= (u256(1) << (integerType->getNumBits() - forSignBit))) + return true; + return false; } - - return integerType->isImplicitlyConvertibleTo(_convertTo); + else + if (_convertTo.getCategory() == Category::FixedBytes) + { + FixedBytesType const& fixedBytes = dynamic_cast(_convertTo); + return fixedBytes.getNumBytes() * 8 >= getIntegerType()->getNumBits(); + } + else + return false; } bool IntegerConstantType::isExplicitlyConvertibleTo(Type const& _convertTo) const @@ -514,9 +525,10 @@ shared_ptr IntegerConstantType::getIntegerType() const if (value > u256(-1)) return shared_ptr(); else - return make_shared(max(bytesRequired(value), 1u) * 8, - negative ? IntegerType::Modifier::Signed - : IntegerType::Modifier::Unsigned); + return make_shared( + max(bytesRequired(value), 1u) * 8, + negative ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned + ); } shared_ptr FixedBytesType::smallestTypeForLiteral(string const& _literal) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index e7287b399..1d0f1fc22 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -4177,10 +4177,14 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_signed) char const* sourceCode = R"( contract test { int8 public x = 2; + int8 public y = 127; + int16 public q = 250; } )"; compileAndRun(sourceCode, 0, "test"); BOOST_CHECK(callContractFunction("x()") == encodeArgs(2)); + BOOST_CHECK(callContractFunction("y()") == encodeArgs(127)); + BOOST_CHECK(callContractFunction("q()") == encodeArgs(250)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 48404aaac..a35b7bbe1 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1816,6 +1816,46 @@ BOOST_AUTO_TEST_CASE(string_length) BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } +BOOST_AUTO_TEST_CASE(negative_integers_to_signed_out_of_bound) +{ + char const* sourceCode = R"( + contract test { + int8 public i = -129; + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(negative_integers_to_signed_min) +{ + char const* sourceCode = R"( + contract test { + int8 public i = -128; + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode)); +} + +BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound) +{ + char const* sourceCode = R"( + contract test { + int8 public j = 128; + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound_max) +{ + char const* sourceCode = R"( + contract test { + int8 public j = 127; + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode)); +} + BOOST_AUTO_TEST_SUITE_END() } From 9da464ee05c0914017394d735c7edb90b48e318a Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Thu, 4 Jun 2015 12:42:55 +0200 Subject: [PATCH 3/5] - style fixes - added test for uint8 = -1 which doesn't fail; todo: fix that --- libsolidity/AST.cpp | 15 +++++++-------- libsolidity/Types.cpp | 11 +++++------ .../libsolidity/SolidityNameAndTypeResolution.cpp | 10 ++++++++++ 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index a209235dc..c6aebd4f4 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -686,14 +686,13 @@ void Expression::expectType(Type const& _expectedType) checkTypeRequirements(nullptr); Type const& type = *getType(); if (!type.isImplicitlyConvertibleTo(_expectedType)) - BOOST_THROW_EXCEPTION( - createTypeError( - "Type " + - type.toString() + - " is not implicitly convertible to expected type " + - _expectedType.toString() + - "." - ) + BOOST_THROW_EXCEPTION(createTypeError( + "Type " + + type.toString() + + " is not implicitly convertible to expected type " + + _expectedType.toString() + + "." + ) ); } diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index c4238f773..c10e29eaa 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -361,22 +361,21 @@ IntegerConstantType::IntegerConstantType(Literal const& _literal) bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) const { - if (IntegerType const* integerType = dynamic_cast(&_convertTo)) + if (auto targetType = dynamic_cast(&_convertTo)) { if (m_value == 0) return true; - int forSignBit = (integerType->isSigned() ? 1 : 0); + int forSignBit = (targetType->isSigned() ? 1 : 0); if (m_value > 0) { - if (m_value <= (u256(-1) >> (256 - integerType->getNumBits() + forSignBit))) + if (m_value <= (u256(-1) >> (256 - targetType->getNumBits() + forSignBit))) return true; } - else if (-m_value <= (u256(1) << (integerType->getNumBits() - forSignBit))) + else if (-m_value <= (u256(1) << (targetType->getNumBits() - forSignBit))) return true; return false; } - else - if (_convertTo.getCategory() == Category::FixedBytes) + else if (_convertTo.getCategory() == Category::FixedBytes) { FixedBytesType const& fixedBytes = dynamic_cast(_convertTo); return fixedBytes.getNumBytes() * 8 >= getIntegerType()->getNumBits(); diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index a35b7bbe1..4f7b82ec7 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1856,6 +1856,16 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound_max) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode)); } +BOOST_AUTO_TEST_CASE(negative_integers_to_unsigned) +{ + char const* sourceCode = R"( + contract test { + uint8 public x = -1; + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From ee2b5e7cb42f6eeec238ec17d8037a1341c940b0 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Thu, 4 Jun 2015 14:09:19 +0200 Subject: [PATCH 4/5] fixed assigning negative number to unsigned --- libsolidity/Types.cpp | 2 +- test/libsolidity/SolidityNameAndTypeResolution.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index c10e29eaa..bf79be310 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -371,7 +371,7 @@ bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) cons if (m_value <= (u256(-1) >> (256 - targetType->getNumBits() + forSignBit))) return true; } - else if (-m_value <= (u256(1) << (targetType->getNumBits() - forSignBit))) + else if (targetType->isSigned() && -m_value <= (u256(1) << (targetType->getNumBits() - forSignBit))) return true; return false; } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 4f7b82ec7..3691868cc 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1866,6 +1866,16 @@ BOOST_AUTO_TEST_CASE(negative_integers_to_unsigned) BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } +BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound) +{ + char const* sourceCode = R"( + contract test { + uint8 public x = 700; + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From f604ab72ee1f0d69ee486757eedcb6a8854e7ef8 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Thu, 4 Jun 2015 18:06:06 +0200 Subject: [PATCH 5/5] Update Types.cpp --- libsolidity/Types.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index bf79be310..33eafb150 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -376,12 +376,12 @@ bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) cons return false; } else if (_convertTo.getCategory() == Category::FixedBytes) - { - FixedBytesType const& fixedBytes = dynamic_cast(_convertTo); - return fixedBytes.getNumBytes() * 8 >= getIntegerType()->getNumBits(); - } - else - return false; + { + FixedBytesType const& fixedBytes = dynamic_cast(_convertTo); + return fixedBytes.getNumBytes() * 8 >= getIntegerType()->getNumBits(); + } + else + return false; } bool IntegerConstantType::isExplicitlyConvertibleTo(Type const& _convertTo) const