Warn if decimal literals are used in a bytesXX context

Fixes #2349
This commit is contained in:
Federico Bond 2017-06-22 11:14:14 -03:00
parent 26ea9ce07c
commit 7a3ea61ffd
2 changed files with 50 additions and 3 deletions

View File

@ -22,6 +22,7 @@
#include <libsolidity/analysis/TypeChecker.h> #include <libsolidity/analysis/TypeChecker.h>
#include <memory> #include <memory>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/range/adaptor/reversed.hpp> #include <boost/range/adaptor/reversed.hpp>
#include <libsolidity/ast/AST.h> #include <libsolidity/ast/AST.h>
#include <libsolidity/inlineasm/AsmAnalysis.h> #include <libsolidity/inlineasm/AsmAnalysis.h>
@ -1793,7 +1794,23 @@ void TypeChecker::expectType(Expression const& _expression, Type const& _expecte
_expectedType.toString() + _expectedType.toString() +
"." "."
); );
} }
if (
type(_expression)->category() == Type::Category::RationalNumber &&
_expectedType.category() == Type::Category::FixedBytes
)
{
auto literal = dynamic_cast<Literal const*>(&_expression);
if (literal && !boost::starts_with(literal->value(), "0x"))
m_errorReporter.warning(
_expression.location(),
"Decimal literal assigned to bytesXX variable will be left-aligned. "
"Use an explicit conversion to silence this warning."
);
}
} }
void TypeChecker::requireLValue(Expression const& _expression) void TypeChecker::requireLValue(Expression const& _expression)

View File

@ -2173,6 +2173,36 @@ BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1)
ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Type resolving failed"); ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Type resolving failed");
} }
BOOST_AUTO_TEST_CASE(warns_assigning_decimal_to_bytesxx)
{
char const* text = R"(
contract Foo {
bytes32 a = 7;
}
)";
CHECK_WARNING(text, "Decimal literal assigned to bytesXX variable will be left-aligned.");
}
BOOST_AUTO_TEST_CASE(does_not_warn_assigning_hex_number_to_bytesxx)
{
char const* text = R"(
contract Foo {
bytes32 a = 0x1234;
}
)";
CHECK_SUCCESS_NO_WARNINGS(text);
}
BOOST_AUTO_TEST_CASE(explicit_conversion_from_decimal_to_bytesxx)
{
char const* text = R"(
contract Foo {
bytes32 a = bytes32(7);
}
)";
CHECK_SUCCESS_NO_WARNINGS(text);
}
BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable) BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable)
{ {
char const* text = R"( char const* text = R"(
@ -3698,12 +3728,12 @@ BOOST_AUTO_TEST_CASE(conditional_with_all_types)
byte[2] memory a; byte[2] memory a;
byte[2] memory b; byte[2] memory b;
var k = true ? a : b; var k = true ? a : b;
k[0] = 0; //Avoid unused var warning k[0] = byte(0); //Avoid unused var warning
bytes memory e; bytes memory e;
bytes memory f; bytes memory f;
var l = true ? e : f; var l = true ? e : f;
l[0] = 0; // Avoid unused var warning l[0] = byte(0); // Avoid unused var warning
// fixed bytes // fixed bytes
bytes2 c; bytes2 c;